package com.zb.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.util.concurrent.RateLimiter;
import com.zb.callback.service.impl.LKaiPushServiceImpl;
import com.zb.code.service.ConCodeService;
import com.zb.constant.NetworkConstant;
import com.zb.constant.WorkConstant;
import com.zb.enums.SmsCode;
import com.zb.excel.converter.WorkConverter;
import com.zb.entity.*;
import com.zb.exception.SMSException;
import com.zb.exception.ZbException;
import com.zb.extend.*;
import com.zb.factory.service.ConFactoryAccountBalanceService;
import com.zb.job.EngineerReceiveTimeoutJob;
import com.zb.job.NetworkDispatchTimeoutJob;
import com.zb.job.NetworkReceiveTimeoutJob;
import com.zb.mapper.*;
import com.zb.order.service.ConWorkOrderService;
import com.zb.order.service.ConWorkSpareService;
import com.zb.order.service.WorkSlaUtilService;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.service.impl.WorkServiceLog;
import com.zb.service.SmsVerificCodeService;
import com.zb.service.impl.WorkUtilService;
import com.zb.sms.entity.*;
import com.zb.sms.service.SmsSendMessageService;
import com.zb.utils.RandomUtil;
import com.zb.utils.ZbDateConvertUtil;
import com.zb.utils.ZbDateUtil;
import com.zb.view.ViewGoods;
import com.zb.view.ViewNetworkEmpAccount;
import com.zb.view.ViewNetworkEmpDetail;
import com.zb.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author WEN
 * @Date 2023/9/20 0020
 **/
@Slf4j
@Service
@EnableScheduling
public class ConWorkOrderServiceImpl implements ConWorkOrderService {
    @Resource
    private ZjUserService userService;
    @Resource
    private ConCodeService conCodeService;
    @Resource
    private ZjWorkGoodsService workGoodsService;
    @Resource
    private ZjWorkGoodsCodeService workGoodsCodeService;
    @Resource
    private ViewGoodsService viewGoodsService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjWorkDetailService workDetailService;
    @Resource
    private ZjWorkImageService workImageService;
    @Resource
    private ZjWorkUserService workUserService;
    @Resource
    private ZjWorkLevelService workLevelService;
    @Resource
    private ZjWorkModuleService workModuleService;
    @Resource
    private ZjWorkReminderService workReminderService;
    @Resource
    private ZjAccountService accountService;
    @Resource
    private ZjCodeUserRegisterService codeUserRegisterService;
    @Resource
    private ZjWorkFieldValService workFieldValService;
    @Resource
    private ZjWorkFieldValOptionService workFieldValOptionService;
    @Resource
    private ZjNetworkService networkService;
    @Resource
    private ZjNetworkStrategyService networkStrategyService;
    @Resource
    private ViewNetworkEmpDetailService viewNetworkEmpDetailService;
    @Resource
    private ViewNetworkEmpAccountService viewNetworkEmpAccountService;
    @Resource
    private ZjWorkDispatchNetworkService workDispatchNetworkService;
    @Resource
    private ZjWorkDispatchEngineerService workDispatchEngineerService;
    @Resource
    private ZjNetworkEmpService networkEmpService;
    @Resource
    private ZjWorkReassignService workReassignService;
    @Resource
    private ZjNetworkModuleSettlementService networkModuleSettlementService;
    @Resource
    private ZjWorkEmpChangeLogService workEmpChangeLogService;
    @Resource
    private ZjWorkLeaveMessageService workLeaveMessageService;
    @Resource
    private ZjWorkLeaveMessageAnnexService workLeaveMessageAnnexService;
    @Resource
    private ZjWorkOrderByFieldService workOrderByFieldService;
    @Resource
    private ZjWorkTableFieldService workTableFieldService;
    @Resource
    private ZjWorkFeeDetailService workFeeDetailService;
    @Resource
    private ZjWorkSpareMaterialService workSpareMaterialService;
    @Resource
    private ZjWorkFinishOrderService workFinishOrderService;
    @Resource
    private ZjWorkFinishOrderTemplateService workFinishOrderTemplateService;
    @Resource
    private ZjWorkFinishOrderTemplateFieldValService workFinishOrderTemplateFieldValService;
    @Resource
    private ZjWorkCancelService workCancelService;
    @Resource
    private ZjFactoryService factoryService;
    @Resource
    private ZjFactoryAccountBalanceService factoryAccountBalanceService;
    @Resource
    private WorkSlaUtilService workSlaUtilService;
    @Resource
    private ZjWorkTotalFeeFreezeService workTotalFeeFreezeService;
    @Resource
    private ZjFactoryOrderDeductionBillService factoryOrderDeductionBillService;
    @Resource
    private ZjNetworkEmpRelationService networkEmpRelationService;
    @Resource
    private ZjWorkChangeEngineerService workChangeEngineerService;
    @Resource
    private ConFactoryAccountBalanceService conFactoryAccountBalanceService;
    @Resource
    private ZjFactoryUserService factoryUserService;
    @Resource
    private ZjWorkSlaConditionService workSlaConditionService;
    @Resource
    private ZjWorkReservationLogService workReservationLogService;
    @Resource
    private ZjWithdrawSetService withdrawSetService;
    @Resource
    private ZjWithdrawService withdrawService;
    @Resource
    private ZjNetworkMapper networkMapper;
    @Resource
    private ConWorkSpareService conWorkSpareService;
    @Resource
    private ZjWorkFeeDetailMapper  workFeeDetailMapper;
    @Autowired
    private ZjWorkOrderMapper zjWorkOrderMapper;
    @Autowired
    private ZjNetworkEmpLevelMapper networkEmpLevelMapper;
    @Resource
    private ZjNetworkEmpLevelRelationService networkEmpLevelRelationService;

    @Autowired
    private ZjAccountRoleMapper zjAccountRoleMapper;

    @Autowired
    private ZjWorkFinishOrderMapper zjWorkFinishOrderMapper;
    @Autowired
    private ZjWithdrawOrderMapper zjWithdrawOrderMapper;
    @Resource
    private ZjWithdrawOrderService withdrawOrderService;

    @Resource
    private ZjWorkSlaModuleMapper zjWorkSlaModuleMapper;
    @Resource
    private ZjWorkSlaConditionMapper zjWorkSlaConditionMapper;

    private final RateLimiter rateLimiter = RateLimiter.create(0.5);

    // 创建、修改工单
    @Override
    @Transactional
    public Map<String, Object> save(AccounLoginInfo loginInfo, boolean isUserMobileOrder, OrderVo orderVo) {
        if (!rateLimiter.tryAcquire()) { // 尝试获取许可
            return null;
        }
        OrderUserVo userVo = orderVo.getOrderUser();
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userVo, userInfo);
        userVo.setUserId(userService.save(loginInfo, userInfo));
        factoryUserService.save(loginInfo.getCustAccId(), orderVo.getFactoryId(), userVo.getUserId());

        if (null != orderVo.getDelOrderGoodsIds() && !orderVo.getDelOrderGoodsIds().isEmpty()) {
            workGoodsCodeService.deleteBatchByWorkGoodsIds(orderVo.getDelOrderGoodsIds());
            workGoodsService.removeByIds(orderVo.getDelOrderGoodsIds());
        }
        List<OrderGoodsVo> orderGoodsVos = new ArrayList<>();
        for (OrderGoodsTypeVo goodsType : orderVo.getOrderGoodsTypes()) {
            orderGoodsVos.addAll(goodsType.getOrderGoodsVos());
            if (1 == goodsType.getType()) {
                conCodeService.getCodeRegister(loginInfo, goodsType.getOrderGoodsVos(), userVo);
                continue;
            }
            if (2 == goodsType.getType()) {
                conCodeService.codeRegister(loginInfo, goodsType.getOrderGoodsVos(), userVo);
                continue;
            }
            if (3 == goodsType.getType()) {
                List<Long> goodsIdSet = goodsType.getOrderGoodsVos().stream().map(OrderGoodsVo::getGoodsId).distinct().toList();
                List<Long> goodsSpecIdSet = goodsType.getOrderGoodsVos().stream().map(OrderGoodsVo::getGoodsSpecId).distinct().toList();
                List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIdSet, goodsSpecIdSet);
                List<CodeVo> codeVos = goodsType.getOrderGoodsVos().stream().map(vo -> {
                    CodeVo codeVo = new CodeVo();
                    BeanUtils.copyProperties(vo, codeVo);
                    codeVo.setWarrantyDay(viewGoodsList.stream().filter(gsv -> Objects.equals(1, gsv.getGoodsType()) &&Objects.equals(gsv.getId(), vo.getGoodsId()) &&
                            Objects.equals(gsv.getSpecId(), vo.getGoodsSpecId())).map(ViewGoods::getWarrantyDay).findFirst().orElse(30));
                    return codeVo;
                }).toList();

                // 创建临时编码
                Map<String, List<Long>> map = conCodeService.saveProductTemporaryCode(loginInfo, codeVos, userVo);

                goodsType.getOrderGoodsVos().forEach(t -> t.setCodeIds(map.get(t.getGoodsId() + "_" + t.getGoodsSpecId())));

                goodsType.getOrderGoodsVos().stream().forEach(t -> {
                    t.setGoodsCodes(codeVos.stream().filter(co -> Objects.equals(co.getGoodsId(), t.getGoodsId()) && Objects.equals(co.getGoodsSpecId(), t.getGoodsSpecId())).map(CodeVo::getGoodsCodes).findFirst().orElse(null));
                    CodeVo codeVo = null;
                    if (null == t.getBuyTime()) {
                        codeVo = codeVos.stream().filter(co -> Objects.equals(co.getGoodsId(), t.getGoodsId()) && Objects.equals(co.getGoodsSpecId(), t.getGoodsSpecId())).findFirst().orElse(null);
                        t.setBuyTime(null != codeVo? codeVo.getWarrantStartTime() : null);
                        t.setEndTime(null != codeVo? codeVo.getWarrantEndTime() : null);
                        return;
                    }
                    if (null == t.getEndTime()) {
                        codeVo = codeVos.stream().filter(co -> Objects.equals(co.getGoodsId(), t.getGoodsId()) && Objects.equals(co.getGoodsSpecId(), t.getGoodsSpecId())).findFirst().orElse(null);
                        t.setEndTime(null != codeVo? codeVo.getWarrantEndTime() : null);
                    }
                });
            }
        }
        String orderVoStringJson = JSON.toJSONString(orderVo);
        Map<String, Object> save = workOrderService.save(loginInfo, isUserMobileOrder, orderVo, orderGoodsVos);
        Long orderId = Long.parseLong(String.valueOf(save.get("id")));
        ZjWorkOrderArgCopy zjWorkOrderArgCopy = new ZjWorkOrderArgCopy();
        zjWorkOrderArgCopy.setOrderId(orderId);
        zjWorkOrderArgCopy.setInfo(orderVoStringJson);
        zjWorkOrderArgCopy.setCreatTime(orderVo.getCreateTime());
        zjWorkOrderMapper.insertOrderArgInfo(zjWorkOrderArgCopy);
        return save;
    }

    /**
     * 复制工单
     * @param loginInfo
     * @param isUserMobileOrder
     * @param orderId
     */
    public OrderVo copySave(AccounLoginInfo loginInfo, boolean isUserMobileOrder, Long orderId) {
//        ZjWorkOrderArgCopy orderArgInfo = zjWorkOrderMapper.getOrderArgInfo(orderId);
//        if (orderArgInfo == null){
//            return null;
//        }
//        return JSON.parseObject(orderArgInfo.getInfo(), OrderVo.class);
        OrderDetailVo orderDetail = getOrderDetail(orderId);
        if (orderDetail == null) return null;
        ZjWorkOrder order = zjWorkOrderMapper.selectById(orderId);
        if (order == null) return null;

        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order, orderVo);
        BeanUtils.copyProperties(orderDetail, orderVo);

        ZjWorkUser workUser = workUserService.getById(orderId);
        if (workUser != null){
            OrderUserVo orderUserVo = new OrderUserVo();
            BeanUtils.copyProperties(workUser, orderUserVo);
            orderVo.setOrderUser(orderUserVo);
        }
        List<WorkGoodsExtend> workGoodsExtendList = workGoodsService.getByWorkId(orderId);
        if (CollectionUtil.isNotEmpty(workGoodsExtendList)){
            List<OrderGoodsTypeVo> orderGoodsTypeVoList = new ArrayList<>();
            List<OrderGoodsVo> orderGoodsVoList = new ArrayList<>();
            workGoodsExtendList.forEach(i ->{
                OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
                BeanUtils.copyProperties(i, orderGoodsVo);
                orderGoodsVoList.add(orderGoodsVo);
            });

            List<Long> workGoodsIds = workGoodsExtendList.stream().map(i -> i.getId()).collect(Collectors.toList());
            List<ZjWorkGoodsCode> workGoodsCodeList = workGoodsCodeService.getByWorkGoodsIds(workGoodsIds);
            OrderGoodsTypeVo orderGoodsTypeVo = new OrderGoodsTypeVo();

            if (CollectionUtil.isNotEmpty(workGoodsCodeList)) {
                Long codeId = workGoodsCodeList.get(0).getCodeId();
                ZjCodeUserRegister codeUserRegister = codeUserRegisterService.getById(codeId);
                if (codeUserRegister != null){
                    orderGoodsTypeVo.setType(1);
                }else {
                    orderGoodsTypeVo.setType(2);
                }

                orderGoodsVoList.forEach(i -> {
                    List<ZjWorkGoodsCode> subWorkGoodsCodeList = workGoodsCodeList.stream().filter(j -> Objects.equals(i.getId(), j.getWorkGoodsId())).collect(Collectors.toList());
                    List<OrderGoodsCodeVo> goodsCodes = new ArrayList<>();
                    for (ZjWorkGoodsCode workGoodsCode : subWorkGoodsCodeList){
                        OrderGoodsCodeVo orderGoodsCodeVo = new OrderGoodsCodeVo();
                        orderGoodsCodeVo.setCodeId(workGoodsCode.getCodeId());
                        orderGoodsCodeVo.setCode(workGoodsCode.getCode());
                        goodsCodes.add(orderGoodsCodeVo);
                    }
                    i.setGoodsCodes(goodsCodes);
                });
            }else {
                orderGoodsTypeVo.setType(3);
            }
            orderGoodsTypeVo.setOrderGoodsVos(orderGoodsVoList);
            orderGoodsTypeVoList.add(orderGoodsTypeVo);
            orderVo.setOrderGoodsTypes(orderGoodsTypeVoList);
        }
        return orderVo;
    }

    // 获取工单列表
    @Override
    public Map<String, Object> getList(AccounLoginInfo loginInfo, OrderListSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        Long custAccId = loginInfo.getCustAccId();
        long totalCount = workOrderService.getListCount(custAccId, selectVo);
        if (totalCount <= 0) {
            return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), totalCount, new ArrayList<>());
        }
        // 获取自定义排序
        selectVo.setOrderBy(workOrderByFieldService.getOrderTableOrderByFieldByCustAccIdAndAccountIdAndType(loginInfo, 1, selectVo.getStatus()));
        List<WorkOrderExtend> orderExtends = workOrderService.getOrderList(loginInfo.getCustAccId(), selectVo);
        // 获取列表字段
        List<WorkTableFieldListVo> orderTableField = workTableFieldService.getOrderListTableField(loginInfo, 1);
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), totalCount, getListData(custAccId, orderExtends, orderTableField));
    }

    // 获取归档列表状态数量
    @Override
    public Map<String, Object> getOrderArchivedStatusQty(Long custAccId) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("finishOrderQty", workOrderService.getOrderArchivedOrderStatusQty(custAccId, WorkConstant.WORK_STATUS_4));
        resultMap.put("cancelOrderQty", workOrderService.getOrderArchivedOrderStatusQty(custAccId, WorkConstant.WORK_STATUS_5));
        return resultMap;
    }

    // 获取工单归档列表
    @Override
    public Map<String, Object> getOrderArchivedList(AccounLoginInfo loginInfo, OrderArchivedListSearchVo searchVo) {
        // 获取自定义排序
        searchVo.setOrderBy(workOrderByFieldService.getOrderTableOrderByFieldByCustAccIdAndAccountIdAndType(loginInfo, 2, searchVo.getStatus()));
        PageUtil.setPageLimit(searchVo);
        List<Long> ids = workOrderService.getOrderArchivedListIdsByPageSearch(loginInfo.getCustAccId(), searchVo);
        if (CollectionUtil.isEmpty(ids)) {
            return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), 0, new ArrayList<>());
        }
        // 获取列表字段
        List<WorkTableFieldListVo> orderTableField = workTableFieldService.getOrderListTableField(loginInfo, 2);
        List<WorkOrderExtend> orderExtends = workOrderService.getList(ids, searchVo.getOrderBy());
        List<OrderListVo> voList = getListData(loginInfo.getCustAccId(), orderExtends, orderTableField);
        if (orderTableField.stream().anyMatch(f -> Objects.equals("archivedTime", f.getCode())))  {
            voList.forEach(t -> {
                orderExtends.stream().filter(f -> null != f.getArchivedTime() && Objects.equals(f.getId(), t.getId())).map(WorkOrderExtend::getArchivedTime).findFirst().ifPresent(t::setArchivedTime);
            });
        }
        return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), workOrderService.getOrderArchivedListCount(loginInfo.getCustAccId(), searchVo), voList);
    }

    // 获取结算列表状态数量
    @Override
    public OrderSettlementStatusQtyVo getOrderSettlementStatusQty(Long custAccId) {
        return workOrderService.getOrderSettlementStatusQty(custAccId);
    }

    // 获取工单结算列表
    @Override
    public Map<String, Object> getOrderSettlementList(AccounLoginInfo loginInfo, OrderSettlementListSearchVo searchVo) {
        PageUtil.setPageLimit(searchVo);
        List<Long> ids = workOrderService.getOrderSettlementListIdsByPageSearch(loginInfo.getCustAccId(), searchVo);
        if (CollectionUtil.isEmpty(ids)) {
            return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), 0, new ArrayList<>());
        }
        // 获取列表字段
        List<WorkTableFieldListVo> orderTableField = workTableFieldService.getOrderListTableField(loginInfo, 3);
        List<WorkOrderExtend> orderExtends = workOrderService.getOrderSettlementList(ids, searchVo);
        List<OrderListVo> voList = getListData(loginInfo.getCustAccId(), orderExtends, orderTableField);
        return PageUtil.pageList(searchVo.getPage(), searchVo.getLimit(), workOrderService.getOrderSettlementListCount(loginInfo.getCustAccId(), searchVo), voList);
    }

    /**
     * 工单列表数据共同方法
     * @param custAccId
     * @param orderTableField
     * @return
     */
    private List<OrderListVo> getListData(Long custAccId, List<WorkOrderExtend> orderExtends, List<WorkTableFieldListVo> orderTableField) {
        List<Long> workIds = orderExtends.stream().map(WorkOrderExtend::getId).toList();
        // 工单模块
        List<Long> moduleIds = orderExtends.stream().map(WorkOrderExtend::getModuleId).distinct().toList();
        boolean module = orderTableField.stream().anyMatch(f -> Objects.equals("module", f.getCode()));
        List<ZjWorkModule> moduleList = new ArrayList<>();
        if (module) {
            moduleList.addAll(workModuleService.getPartInfoByIds(moduleIds));
        }
        // 客服
        List<ZjAccount> accountList = new ArrayList<>();
        boolean emp = orderTableField.stream().anyMatch(f -> Objects.equals("emp", f.getCode()));
        if (emp) {
            List<Long> empIds = orderExtends.stream().map(WorkOrderExtend::getEmpId).distinct().toList();
            if (CollectionUtil.isNotEmpty(empIds)) accountList.addAll(accountService.getByIds(empIds));
        }
        // 报单商品
        List<WorkGoodsExtend> goodsExtends = new ArrayList<>();
        boolean orderGoods = orderTableField.stream().anyMatch(f -> Objects.equals("orderGoods", f.getCode()));
        if (orderGoods && CollectionUtil.isNotEmpty(workIds)) {
            goodsExtends.addAll(workGoodsService.getByWorkIds(workIds));
        }
        // 工单级别
        List<ZjWorkLevel> levelList = new ArrayList<>();
        boolean workLevel = orderTableField.stream().anyMatch(f -> Objects.equals("workLevel", f.getCode()));
        if (workLevel) {
            List<Long> workLevelIds = orderExtends.stream().map(WorkOrderExtend::getWorkLevelId).distinct().toList();
            if (CollectionUtil.isNotEmpty(workLevelIds)) levelList.addAll(workLevelService.getByIds(workLevelIds));
        }
        // 服务区域
        List<ZjNetwork> networkList = new ArrayList<>();
        boolean network = orderTableField.stream().anyMatch(f -> Objects.equals("network", f.getCode()));
        if (network) {
            List<Long> networkIds = orderExtends.stream().map(ZjWorkOrder::getNetworkId).distinct().toList();
            if (CollectionUtil.isNotEmpty(networkIds)) networkList.addAll(networkService.listByIds(networkIds));
        }
        // 工程师
        boolean engineer = orderTableField.stream().anyMatch(f -> Objects.equals("engineer", f.getCode()));
        List<ViewNetworkEmpDetail> networkEmpDetailList = new ArrayList<>();
        if (engineer) {
            networkEmpDetailList.addAll(viewNetworkEmpDetailService.getByNetworkEmpIds(orderExtends.stream().map(WorkOrderExtend::getNetworkEmpId).filter(f -> null != f && f > 0).toList()));
        }
        // 预约时间
        List<ZjWorkDetail> detailList = new ArrayList<>();
        boolean reservationDate = orderTableField.stream().anyMatch(f -> Objects.equals("reservationDate", f.getCode()));
        if (reservationDate && CollectionUtil.isNotEmpty(workIds)) {
            detailList.addAll(workDetailService.listByIds(workIds));
        }
        //工单详情
        boolean content = orderTableField.stream().anyMatch(f -> Objects.equals("content", f.getCode()));
        if (content && CollectionUtil.isNotEmpty(workIds)) {
            List<ZjWorkDetail> list = workDetailService.listByIds(workIds);
            detailList.addAll(list);
        }
        // 节点时效/服务时长
        List<OrderSlaVo> orderSlaInfo = new ArrayList<>();
        boolean serviceTime = orderTableField.stream().anyMatch(f -> Objects.equals("serviceTime", f.getCode()));
        if (serviceTime) {
            List<OrderSlaSelectVo> orderSlaSelectVos = orderExtends.stream().map(order -> {
               return new OrderSlaSelectVo(order.getId(), order.getModuleId(), order.getStatus(), null != order.getAssignEmp() && order.getAssignEmp(), order.getGmtCreate(), order.getGmtUpdate());
            }).toList();
            orderSlaInfo.addAll(workSlaUtilService.getOrderSlaInfo(orderSlaSelectVos));
        }
        // 品牌商家
        List<ZjFactory> factoryList = new ArrayList<>();
        boolean factory = orderTableField.stream().anyMatch(f -> Objects.equals("factory", f.getCode()));
        if (factory) {
            List<Long> factoryIds = orderExtends.stream().map(WorkOrderExtend::getFactoryId).distinct().toList();
            if (CollectionUtil.isNotEmpty(factoryIds)) factoryList.addAll(factoryService.getNameByIds(factoryIds));
        }
        // 商家结算总价
        boolean factorySettlementTotalPrice = orderTableField.stream().anyMatch(f -> Objects.equals("factorySettlementTotalPrice", f.getCode()));
        // 服务商结算总价
        boolean networkSettlementTotalPrice = orderTableField.stream().anyMatch(f -> Objects.equals("networkSettlementTotalPrice", f.getCode()));
        // 工单费用
        List<OrderSettlementPriceVo> settlementPriceVoList = new ArrayList<>();
//        List<ZjWorkFeeDetail>  workFeeDetails = new ArrayList<>();
//        List<ZjWorkSpareMaterial> workSpareMaterials = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(workIds) && (factorySettlementTotalPrice || networkSettlementTotalPrice)) {
            settlementPriceVoList.addAll(workOrderService.getOrderSettlementPriceByWorkId(workIds));
//            workFeeDetails.addAll(workFeeDetailService.getOrderSettlementFeeByWorkId(workIds));
//            workSpareMaterials.addAll(workSpareMaterialService.getOrderSettlementFeeByWorkId(workIds));
        }
        // 异常费用
        boolean abnormalFee = orderTableField.stream().anyMatch(f -> Objects.equals("abnormalFee", f.getCode()));
        List<ZjWorkFeeDetail>  errorFees = new ArrayList<>();
        if (abnormalFee && CollectionUtil.isNotEmpty(workIds)) {
            errorFees.addAll(workFeeDetailService.getExceptionFeeByWorkIds(workIds));
        }
        // 平台承担费用
        List<ZjWorkFieldVal> workFieldValList = workFieldValService.getOrderListShowFieldByModuleIds(moduleIds);
        List<ZjWorkFieldValOption> fieldValOptions = workFieldValOptionService.getByWorkFieldValIds(workFieldValList.stream().map(ZjWorkFieldVal::getId).toList());
        // 服务过程 serviceProcess
        boolean serviceProcess = orderTableField.stream().anyMatch(f -> Objects.equals("serviceProcess", f.getCode()));
        List<ZjWorkLeaveMessage> leaveMessageList = new ArrayList<>();
        if (serviceProcess && CollectionUtil.isNotEmpty(workIds)) {
            leaveMessageList.addAll(workLeaveMessageService.getLastByWorkIds(workIds));
        }
        StringBuilder goodsBuilder = new StringBuilder();
        return orderExtends.stream().map(order -> {
            OrderListVo vo = new OrderListVo();
            vo.setId(order.getId());
            vo.setIsHx(order.getIsHx());
            vo.setIsPause(order.getIsPause());
            vo.setIsReturn(order.getIsReturn());
            vo.setExpressCompany(order.getExpressCompany());
            vo.setExpressNbr(order.getExpressNbr());
            vo.setFactorySettlementPrice(order.getModulePrice());
            vo.setNetworkSettlementPrice(order.getNetworkModulePrice());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("code", f.getCode()))) vo.setCode(order.getCode());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("createTime", f.getCode()))) vo.setCreateTime(order.getGmtCreate());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("status", f.getCode()))) vo.setStatus(order.getStatus());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("source", f.getCode()))) vo.setSource(order.getSource());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("factoryRemark", f.getCode()))) vo.setFactoryRemark(order.getFactoryRemark());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("updateTime", f.getCode()))) vo.setUpdateTime(order.getGmtUpdate());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("orderFinishTime", f.getCode()))) vo.setOrderFinishTime(order.getEndTime());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("orderCancelTime", f.getCode()))) vo.setOrderCancelTime(order.getCancelTime());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("userName", f.getCode()))) vo.setUserName(order.getUserName());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("userPhone", f.getCode()))) vo.setUserPhone(order.getUserPhone());
            if (orderTableField.stream().anyMatch(f -> Objects.equals("userAddress", f.getCode()))) {
                vo.setProvince(order.getProvince());
                vo.setCity(order.getCity());
                vo.setArea(order.getArea());
                vo.setTown(order.getTown());
                vo.setAddress(order.getAddress());
            }
            if (factory) {
                factoryList.stream().filter(f -> Objects.equals(f.getId(), order.getFactoryId())).findFirst().map(ZjFactory::getName).ifPresent(vo::setFactory);
            }
            // 商家结算总价
            if (factorySettlementTotalPrice) {
                vo.setFactorySettlementTotalPrice(order.getModulePrice()
                        .add(settlementPriceVoList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().map(OrderSettlementPriceVo::getReceiveFactoryPrice).orElse(new BigDecimal("0.00")))
                        .subtract(order.getFactorySettlementDeductionPrice() != null ? order.getFactorySettlementDeductionPrice() : new BigDecimal("0.00")));
                vo.setFactorySettlementPrice(vo.getFactorySettlementTotalPrice());
            }
            // 网点结算总价
            if (networkSettlementTotalPrice) {
                    vo.setNetworkSettlementTotalPrice(order.getNetworkModulePrice()
                            .add(settlementPriceVoList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().map(OrderSettlementPriceVo::getPayNetworkPrice).orElse(new BigDecimal("0.00")))
                            .subtract(order.getNetworkSettlementDeductionPrice() != null ? order.getNetworkSettlementDeductionPrice() : new BigDecimal("0.00")));
                vo.setNetworkSettlementPrice(vo.getNetworkSettlementTotalPrice());
            }
            if (abnormalFee) {
                vo.setAbnormalFee(errorFees.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().map(ZjWorkFeeDetail::getPayNetworkPrice).orElse(new BigDecimal("0.0")));
            }
            if (orderTableField.stream().anyMatch(f -> Objects.equals("orderGoodsQty", f.getCode()))) {
                vo.setOrderGoodsQty(goodsExtends.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId()))
                        .map(WorkGoodsExtend::getQty).reduce(Integer::sum).orElse(1));
            }
            if (module){
                moduleList.stream().filter(f -> Objects.equals(f.getId(), order.getModuleId())).findFirst().ifPresent(mo -> vo.setModule("【" + WorkConverter.moduleTypeConverter(mo.getType()) + "】" + mo.getName()));
            }
            if (orderGoods) {
                goodsExtends.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).forEach(goodsExtend -> {
                    goodsBuilder.append(goodsExtend.getGoodsBrand()).append("、").append(goodsExtend.getGoodsModel()).append("、").append(goodsExtend.getGoodsSpecName()).append("；");
                });
                vo.setOrderGoods(goodsBuilder.toString());
                goodsBuilder.delete(0, goodsBuilder.length());
            }
            if (workLevel) {
                levelList.stream().filter(f -> Objects.equals(f.getId(), order.getWorkLevelId())).findFirst().ifPresent(level -> {
                    vo.setWorkLevel(level.getName());
                    vo.setWorkLevelColor(level.getColor());
                });
            }
            vo.setNetworkId(order.getNetworkId());
            if (network) {
                networkList.stream().filter(f -> Objects.equals(f.getId(), order.getNetworkId())).findFirst().ifPresent(net -> {
                    vo.setNetwork("【" + (net.getCategory() == NetworkConstant.CATEGORY_1? NetworkConstant.CATEGORY_STR_1 : NetworkConstant.CATEGORY_STR_2) +"】" + net.getName());
                });
            }
            if (engineer) {
                networkEmpDetailList.stream().filter(f -> Objects.equals(f.getId(), order.getNetworkEmpId())).findFirst().ifPresent(networkEmp -> {
                    vo.setEngineer(networkEmp.getAccountName());
                    vo.setEnginnerPhone(networkEmp.getAccountPhone());
                });
            }
            if (orderTableField.stream().anyMatch(f -> Objects.equals("totalServiceTime", f.getCode()))) {
                vo.setTotalServiceTime(ZbDateUtil.getTimeLength(order.getGmtCreate(), order.getStatus() == 4? order.getEndTime() : (order.getStatus() == 5? order.getCancelTime() : new Date())));
            }
            if (reservationDate) {
                detailList.stream().filter(f -> Objects.equals(f.getId(), order.getId())).findFirst().ifPresent(detail -> {
                    if (detail.getReservationDate() != null &&
                            detail.getReservationStartTime() != null &&
                            detail.getReservationEndTime() != null) {

                        String formattedReservationDate =
                                DateUtil.format(detail.getReservationDate(), "yyyy-MM-dd") + " " +
                                        DateUtil.format(detail.getReservationStartTime(), "HH:mm") + " ~ " +
                                        DateUtil.format(detail.getReservationEndTime(), "HH:mm");

                        vo.setReservationDate(formattedReservationDate);
                    }
//                    vo.setReservationDate(detail.getReservationDate());
//                    vo.setReservationDate(formattedReservationDate);
                    vo.setReservationStartTime(detail.getReservationStartTime());
                    vo.setReservationEndTime(detail.getReservationEndTime());
                });
            }
            if (content) {
                detailList.stream().filter(f -> Objects.equals(f.getId(), order.getId())).findFirst().ifPresent(detail -> {
                    vo.setContent(detail.getContent());
                });
            }
            if (detailList != null) {
                detailList.stream().filter(f -> Objects.equals(f.getId(), order.getId())).findFirst().ifPresent(detail -> {
                    if (detail.getVerifiedVisitTime() != null) {
                        vo.setIsHs(0);
                    }else {
                        vo.setIsHs(1);
                    }
                });
            }
            if (serviceTime) {
                orderSlaInfo.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().ifPresent(sla -> {
                    vo.setNodeTimeout(sla.isNodeTimeout());
                    vo.setNodeOverTimeType(sla.getType());
                    vo.setNodeOverTime(sla.getNodeTimeoutLength());
                });
            }
            if (emp) {
                accountList.stream().filter(f -> Objects.equals(f.getId(), order.getEmpId())).map(ZjAccount::getName).findFirst().ifPresent(vo::setEmp);
            }
            if (serviceProcess) {
                vo.setServiceProcess(leaveMessageList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().map(ZjWorkLeaveMessage::getContent).orElse(""));
            }
            if(orderTableField.stream().anyMatch(f -> Objects.equals("thirdPushState", f.getCode()))){
                if(order.getThirdPushState()!=null) {
                    vo.setThirdPushState(order.getThirdPushState().equals(1) ? "已推送" : "未推送");
                }
            }
            if(orderTableField.stream().anyMatch(f -> Objects.equals("thirdPushErrorMsg", f.getCode()))){
                vo.setThirdPushErrorMsg(order.getThirdPushErrorMsg());
            }
            if(orderTableField.stream().anyMatch(f -> Objects.equals("thirdStateFinishContentJson", f.getCode()))){
                vo.setThirdStateFinishContentJson(order.getThirdStateFinishContentJson());
            }

            vo.setNewProgress(order.getNewAdvance() > 0 || order.getWaitCopeEvent() > 0);
            vo.setReminder(order.getReminderNum() > 0);
            vo.setReminderCount(order.getReminderNum());
            vo.setFieldVals(workFieldValList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).map(v -> {
                return new WorkListFieldShowVal(v.getWorkFieldId(), v.getName(),
                        fieldValOptions.stream().filter(fo -> Objects.equals(fo.getWorkFieldValId(), v.getId())).map(ZjWorkFieldValOption::getOptValue).collect(Collectors.joining("、")));
            }).toList());
            return vo;
        }).toList();
    }

    // 根据工单ID获取工单详情
    @Override
    public OrderDetailVo getOrderDetail(Long id) {
        ZjWorkOrder order = workOrderService.getById(id);
        Assert.isTrue(null != order, "工单ID参数[" + id + "]的数据不存在！");

        OrderDetailVo vo = new OrderDetailVo();
        BeanUtil.copyProperties(order, vo);
        vo.setOrderNo(order.getCode());

        ZjWorkModule workModule = workModuleService.getById(order.getModuleId());
        vo.setModuleId(order.getModuleId());
        vo.setModule(workModule.getName());
        ZjWorkLevel workLevel = workLevelService.getById(order.getWorkLevelId());
        if (null != workLevel) {
            vo.setWorkLevel(workLevel.getName());
            vo.setWorkLevelColor(workLevel.getColor());
        }
        if (order.getSignImage() != null) {
            List<String> urls = Arrays.asList(order.getSignImage().split(","));
            vo.setSignImageList(urls);
        }
        // 工单节点时间
        OrderSlaVo orderSlaInfo = workSlaUtilService.getOrderSlaInfo(new OrderSlaSelectVo(id, order.getModuleId(), order.getStatus(), order.getAssignEmp(), order.getGmtCreate(), order.getGmtUpdate()));
        if (null != orderSlaInfo) {
            vo.setNodeTimeout(orderSlaInfo.isNodeTimeout());
            vo.setNodeOverTimetype(orderSlaInfo.getType());
            vo.setNodeOverTime(orderSlaInfo.getNodeTimeoutLength());
        }

        ZjWorkUser workUser = workUserService.getById(id);
        ZjUser user = userService.getById(workUser.getUserId());
        vo.setUserId(workUser.getUserId());
//        vo.setUserName(user.getName());
        vo.setUserName(workUser.getName());
        vo.setContacts(workUser.getName());
        vo.setContactsPhone(workUser.getPhone());
//        vo.setOtherPhone(workUser.getOtherPhone());
        vo.setExtensionNbr(workUser.getOtherPhone());
        vo.setProvince(workUser.getProvince());
        vo.setCity(workUser.getCity());
        vo.setArea(workUser.getArea());
        vo.setTown(workUser.getTown());
        vo.setAddress(workUser.getAddress());

        ZjWorkDispatchNetwork dispatchNetwork = workDispatchNetworkService.getByWorkId(id);
        if (null != dispatchNetwork) {
            ZjNetwork network = networkService.getById(dispatchNetwork.getNetworkId());
            ViewNetworkEmpDetail networkManager = viewNetworkEmpDetailService.getManagerByNetworkId(network.getId());
            vo.setNetwork(network.getName());
            vo.setNetworkManaterEmp(networkManager.getAccountName());
            vo.setNetworkManaterPhone(networkManager.getAccountPhone());
            StringBuilder builder = new StringBuilder();
            builder.append(network.getProvince()).append("-")
                    .append(network.getCity()).append("-")
                    .append(network.getArea()).append("-");
            if (StringUtils.isNotBlank(network.getTown())) {
                builder.append(network.getTown()).append("-");
            }
            builder.append(network.getAddress());
            vo.setNetworkAddress(builder.toString());
            vo.setReceivingOrderTime(dispatchNetwork.getReceivingOrderTime());
        }
        ZjWorkDispatchEngineer dispatchEngineer = workDispatchEngineerService.getByNetworkEmpIdAndWorkId(order.getNetworkEmpId(), order.getId());
        if (null != dispatchEngineer) {
            ViewNetworkEmpDetail emp = networkEmpService.getInfoById(dispatchEngineer.getNetworkEmpId());
            // 获取工程师等级
           Long networkEmpLevelId =  networkEmpLevelRelationService.getNetworkEmpLevelIdByNetworkEmpId(order.getCustAccId(), order.getNetworkEmpId());
            QueryWrapper<ZjNetworkEmpLevel> wrapper = new QueryWrapper<>();
            wrapper.select("name")
                    .eq("cust_acc_id", order.getCustAccId()).eq("id", networkEmpLevelId);
            ZjNetworkEmpLevel empLevelName = networkEmpLevelMapper.selectOne(wrapper);
//            if (null != emp){
            if (null != emp && null != empLevelName) {
                vo.setEngineerLevel(empLevelName.getName());//设置工程师等级
                vo.setEngineerManagerEmp(emp.getAccountName());
                vo.setEngineerManagerPhone(emp.getAccountPhone());
                vo.setDispatchOrderEngineerTime(ZbDateConvertUtil.dateStrFormatToDateStr(dispatchEngineer.getDispatchTime()));
                vo.setEngineerReceivingOrderTime(ZbDateConvertUtil.dateStrFormatToDateStr(dispatchEngineer.getReceivingOrderTime()));
            }
        }
        vo.setReminder(order.getReminderNum() > 0);
        vo.setCreateTime(order.getGmtCreate());
//        vo.setExtensionNbr(order.getExtensionNbr());
        ZjAccount account = accountService.getById(order.getEmpId());
        if (null != account) {
            vo.setAssignEmp(true);
            vo.setEmp(account.getName());
        }
        ZjWorkDetail workDetail = workDetailService.getById(id);
        vo.setDispatcOrderTime(workDetail.getDispatchTime());
        vo.setContent(workDetail.getContent());
        vo.setCollectCustomerPriceVoucher(workDetail.getCollectCustomerPriceVoucher());
        vo.setOrderImages(workImageService.getByWorkId(id).stream().map(ZjWorkImage::getImage).toList());
        vo.setStatementVerifCode(workDetail.getStatementVerifCode());
        // 获取关联品牌商家
        ZjFactory factory = factoryService.getById(order.getFactoryId());
        if (null != factory) vo.setFactory(factory.getName());
        vo.setOrderCustomFields(workFieldValService.getOrderFieldParam(id));
        // 更新工单新进展
        workOrderService.updateNewAdvanceOrWaitCopeEventById(order.getId(), 0, null);
        // 冻结状态与冻结天数
        if (order.getStatus() == WorkConstant.WORK_STATUS_4) {
            vo.setFreezeStatus(DateUtils.addDays(order.getEndTime(), order.getWithdrawFreezeDay()).after(new Date())? 1 : 2);
            if (vo.getFreezeStatus() == 1) {
                vo.setFreezeDay((int) ZbDateUtil.getDays(DateUtils.addDays(order.getEndTime(), order.getWithdrawFreezeDay()), new Date()));
            } else {
                ZjWithdraw withdraw = withdrawService.getByWorkId(order.getId());
                if (null != withdraw) {
                    vo.setOrderWithdrawStatus(withdraw.getStatus());
                }
            }
        }
        //客服核实派单时间
        vo.setVerifiedVisitTime(workDetail.getVerifiedVisitTime());
        //查询工单审核表记录
        QueryWrapper<ZjWorkFinishOrder> orderFinishQueryWrapper = new QueryWrapper<>();
        orderFinishQueryWrapper.select("id","status","work_id").eq("work_id",order.getId()).eq("status",2);
        ZjWorkFinishOrder orderFinish = zjWorkFinishOrderMapper.selectOne(orderFinishQueryWrapper);
        //查询该工单是否有提现单
        QueryWrapper<ZjWithdrawOrder> withdrawOrderQueryWrapper = new QueryWrapper<>();
        withdrawOrderQueryWrapper.select("id", "work_id", "work_no")
                .eq("work_id", order.getId());
        ZjWithdrawOrder zjWithdrawOrder = zjWithdrawOrderMapper.selectOne(withdrawOrderQueryWrapper);
        if(zjWithdrawOrder == null && order.getStatus() == WorkConstant.WORK_STATUS_4 && orderFinish != null){
            vo.setCancelOrderStatus(true);
        }else {
            vo.setCancelOrderStatus(false);
        }
        return vo;
    }

    // 根据工单ID获取工单商品
    @Override
    public Map<String, Object> getOrderGoodsDetail(Long workId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("id", "goods_id", "goods_spec_id", "qty", "buy_time", "end_time");
        wrapper.eq("work_id", workId);
        Page<ZjWorkGoods> page = workGoodsService.page(new Page<>(pageUtil.getPage(), pageUtil.getLimit()), wrapper);
        if (page.getTotal() <= 0) {
            return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), new ArrayList<>());
        }
        List<ZjWorkGoods> workGoodsList = page.getRecords();
        List<Long> workGoodsIds = workGoodsList.stream().map(ZjWorkGoods::getId).toList();
        List<ZjWorkGoodsCode> goodsCodeList = workGoodsCodeService.getByWorkGoodsIds(workGoodsIds);
        List<Long> goodsCodeIds = goodsCodeList.stream().map(ZjWorkGoodsCode::getCodeId).distinct().toList();
        List<ZjCodeUserRegister> registerList = codeUserRegisterService.getByIds(goodsCodeIds);

        List<Long> goodsIds = workGoodsList.stream().map(ZjWorkGoods::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = workGoodsList.stream().map(ZjWorkGoods::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);

        List<OrderDetailGoodsVo> voList = workGoodsList.stream().map(goods -> {
            OrderDetailGoodsVo vo = new OrderDetailGoodsVo();
            BeanUtil.copyProperties(goods, vo);
            viewGoodsList.stream().filter(f -> Objects.equals(f.getId(), vo.getGoodsId()) && Objects.equals(f.getSpecId(), vo.getGoodsSpecId())).findFirst().ifPresent(specView -> {
                vo.setGoodsBrandId(specView.getBrandId());
                vo.setGoodsBrand(specView.getBrand());
                vo.setGoodsModel(specView.getModel());
                vo.setGoodsName(specView.getName());
                vo.setGoodsType(specView.getType());
                vo.setGoodsSpec(specView.getSpecName());
            });
            vo.setCodes(goodsCodeList.stream().filter(f -> Objects.equals(f.getWorkGoodsId(), goods.getId())).map(ZjWorkGoodsCode::getCode).toList());
            registerList.stream().filter(f ->
                    goodsCodeList.stream().anyMatch(f2 -> Objects.equals(f.getId(), f2.getCodeId()) && Objects.equals(f2.getWorkGoodsId(), goods.getId()))).findFirst().ifPresent(userRegister -> {
                vo.setUserName(userRegister.getName());
                vo.setUserPhone(userRegister.getPhone());
                vo.setProvince(userRegister.getProvince());
                vo.setCity(userRegister.getCity());
                vo.setArea(userRegister.getArea());
                vo.setTown(userRegister.getTown());
                vo.setAddress(userRegister.getAddress());
            });
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    @Override
    public List<AfterSaleProductVo> getOrderGoodsDetail(Long workId) {
        QueryWrapper<ZjWorkGoods> wrapper = new QueryWrapper<>();
        wrapper.select("id", "goods_id", "goods_spec_id", "qty", "buy_time", "end_time");
        wrapper.eq("work_id", workId);

        // 获取所有工单商品记录
        List<ZjWorkGoods> workGoodsList = workGoodsService.list(wrapper);
        if (workGoodsList.isEmpty()) {
            return new ArrayList<>();  // 如果没有符合条件的数据，返回空的列表
        }

        List<Long> workGoodsIds = workGoodsList.stream().map(ZjWorkGoods::getId).toList();
        List<ZjWorkGoodsCode> goodsCodeList = workGoodsCodeService.getByWorkGoodsIds(workGoodsIds);
        List<Long> goodsCodeIds = goodsCodeList.stream().map(ZjWorkGoodsCode::getCodeId).distinct().toList();
        List<ZjCodeUserRegister> registerList = codeUserRegisterService.getByIds(goodsCodeIds);

        List<Long> goodsIds = workGoodsList.stream().map(ZjWorkGoods::getGoodsId).distinct().toList();
        List<Long> goodsSpecIds = workGoodsList.stream().map(ZjWorkGoods::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(goodsIds, goodsSpecIds);

        List<AfterSaleProductVo> voList = workGoodsList.stream().map(goods -> {
            AfterSaleProductVo vo = new AfterSaleProductVo();
            BeanUtil.copyProperties(goods, vo);

            // 匹配商品详情并填充
            viewGoodsList.stream().filter(f -> Objects.equals(f.getId(), vo.getGoodsId()) && Objects.equals(f.getSpecId(), vo.getGoodsSpecId())).findFirst().ifPresent(specView -> {
                vo.setGoodsBrandId(specView.getBrandId());
                vo.setGoodsBrand(specView.getBrand());
                vo.setGoodsModel(specView.getModel());
                vo.setGoodsName(specView.getName());
                vo.setGoodsType(specView.getType());
                vo.setGoodsSpec(specView.getSpecName());
            });

            // 设置商品的 codes
            vo.setCodes(goodsCodeList.stream().filter(f -> Objects.equals(f.getWorkGoodsId(), goods.getId())).map(ZjWorkGoodsCode::getCode).toList());

            // 匹配用户注册信息
            registerList.stream().filter(f ->
                    goodsCodeList.stream().anyMatch(f2 -> Objects.equals(f.getId(), f2.getCodeId()) && Objects.equals(f2.getWorkGoodsId(), goods.getId()))).findFirst().ifPresent(userRegister -> {
                vo.setUserName(userRegister.getName());
                vo.setUserPhone(userRegister.getPhone());
                vo.setProvince(userRegister.getProvince());
                vo.setCity(userRegister.getCity());
                vo.setArea(userRegister.getArea());
                vo.setTown(userRegister.getTown());
                vo.setAddress(userRegister.getAddress());
            });
            return vo;
        }).toList();

        return voList;
    }

    // 工单预约时间
    @Override
    @Transactional
    public void reservationTime(AccounLoginInfo loginInfo, OrderReservationTimeVo orderReservationTimeVo) {
        ZjWorkOrder workOrder = workOrderService.getById(orderReservationTimeVo.getWorkId());
        Assert.notNull(workOrder, "当前服务工单不存在");
        Assert.isTrue(WorkConstant.WORK_STATUS_3 == workOrder.getStatus(),
                WorkConstant.WORK_STATUS_1 == workOrder.getStatus() ? "当前工单未派单，禁止预约时间" :
                        WorkConstant.WORK_STATUS_2 == workOrder.getStatus() ? "当前工单派单的服务商未确认接单，禁止预约时间" :
                                WorkConstant.WORK_STATUS_4 == workOrder.getStatus() ? "当前工单工单已完工，禁止预约时间" : "当前工单已取消，禁止预约时间"
        );
        ZjWorkModule module = workModuleService.getById(workOrder.getModuleId());
        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(workOrder.getId());
        updateOrder.setUpdateEmpId(loginInfo.getId());
        updateOrder.setUpdateEmp(loginInfo.getName());

        ZjWorkDetail workDetail = new ZjWorkDetail();
        workDetail.setId(workOrder.getId());
        workDetail.setReservation(true);
        if (module.getReservationTimeType() == 3) {
            Assert.isTrue((orderReservationTimeVo.getReservationStartTime().after(module.getReservationStartTime()) || orderReservationTimeVo.getReservationStartTime().getTime() == module.getReservationStartTime().getTime())
                            && (orderReservationTimeVo.getReservationEndTime().before(module.getReservationEndTime()) || orderReservationTimeVo.getReservationEndTime().getTime() == module.getReservationEndTime().getTime()),
                    "预约时间必须在[" + DateUtil.format(module.getReservationStartTime(), "HH:mm") + "~" + DateUtil.format(module.getReservationEndTime(), "HH:mm") +"]之间");
        }
        workDetail.setReservationDate(orderReservationTimeVo.getDate());
        workDetail.setReservationStartTime(orderReservationTimeVo.getReservationStartTime());
        workDetail.setReservationEndTime(orderReservationTimeVo.getReservationEndTime());
        workOrderService.updateById(updateOrder);
        workDetailService.updateById(workDetail);
        String datetime = DateUtil.format(orderReservationTimeVo.getDate(), "yyyy-MM-dd") + " " +
                DateUtil.format(orderReservationTimeVo.getReservationStartTime(), "HH:mm") + " ~ " +
                DateUtil.format(orderReservationTimeVo.getReservationEndTime(), "HH:mm");
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, orderReservationTimeVo.getWorkId(),"客服预约时间",
                "预约上门服务时间为：" + datetime + "；" + orderReservationTimeVo.getRemark()));
        workReservationLogService.saveService(loginInfo, new WorkReservationLogVo()
                .setWorkId(orderReservationTimeVo.getWorkId())
                .setReservationDate(orderReservationTimeVo.getDate())
                .setReservationStartTime(orderReservationTimeVo.getReservationStartTime())
                .setReservationEndTime(orderReservationTimeVo.getReservationEndTime())
                .setRemark(orderReservationTimeVo.getRemark()));
        // 发送短信
        SendOrderReservationTimeVo reservationTimeVo = new SendOrderReservationTimeVo(WorkUtilService.getOrderReceive(workOrder.getId()));
        reservationTimeVo.setReservationDate(orderReservationTimeVo.getDate());
        reservationTimeVo.setReservationStartTime(orderReservationTimeVo.getReservationStartTime());
        reservationTimeVo.setReservationEndTime(orderReservationTimeVo.getReservationEndTime());
        SmsSendMessageService.sendOrderReservationTime(loginInfo, reservationTimeVo);
    }

    // 工单派单给服务商
    @Override
    @Transactional
    public void orderDispatchNetwork(AccounLoginInfo loginInfo, OrderDispatchNetworkVo orderDispatchNetworkVo) {
        log.info("工单派单给服务商入参:{}", orderDispatchNetworkVo);
        QueryWrapper<ZjWorkOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id", "module_id", "code", "status", "module_price");
        wrapper.in("id", orderDispatchNetworkVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(wrapper);
        Assert.isTrue(CollectionUtil.isNotEmpty(orderList), "选定派单的工单不存在");

        List<String> workNos = orderList.stream().filter(o -> WorkConstant.WORK_STATUS_1 != o.getStatus()).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(workNos), "工单单号["+ String.join("、", workNos) +"]的流程状态处于非[待派单]流程，不允许跨流程或重复派单到服务商");

        ZjNetwork network = networkService.getById(orderDispatchNetworkVo.getNetworkId());
        Assert.isTrue(null != network, "指定分派服务工单的服务商不存在");
        if (network.getCategory() == NetworkConstant.CATEGORY_2) {
            // todo 派间到第三方服务
        }
        // 是否指定工程师
        boolean dispatchEngineerFlag = null != orderDispatchNetworkVo.getNetworkEmpId() && orderDispatchNetworkVo.getNetworkEmpId() > 0;
        ViewNetworkEmpDetail empDetailView = null;
        if (dispatchEngineerFlag) {
            empDetailView = viewNetworkEmpDetailService.getByNetworkIdAndNetworkEmpId(orderDispatchNetworkVo.getNetworkId(), orderDispatchNetworkVo.getNetworkEmpId());
            Assert.notNull(empDetailView, "指定派工的工程师不存在");
        }

        List<Long> moduleIds = orderList.stream().map(ZjWorkOrder::getModuleId).distinct().toList();
        List<ZjNetworkModuleSettlement> settlementList = networkModuleSettlementService.getNetworkIdAndModuleIds(orderDispatchNetworkVo.getNetworkId(), moduleIds);
        orderList.forEach(o -> {
            o.setNetworkModulePrice(settlementList.stream().filter(f -> Objects.equals(o.getModuleId(), f.getModuleId())).map(ZjNetworkModuleSettlement::getPrice).findFirst().orElse(new BigDecimal("0.0")));
        });
        // 服务商自动确认接单，仅内部服务商
        boolean networkSureReceiveOrder = false;
        if (network.getCategory() == NetworkConstant.CATEGORY_1) {
            ZjNetworkStrategy sureReceiveOrder = networkStrategyService.isAutoSureReceiveOrder(network.getId());
            networkSureReceiveOrder = sureReceiveOrder.getAutoSureReceiveOrder();
        }
        // 工程师自动确认接单
        boolean networkEngingerSureReceiveOrder = null == empDetailView || empDetailView.getAutoSureReceiveOrder();
        // 查询是否存在派单的历史工单
        List<ZjWorkDispatchNetwork> workDispatchNetworkList = workDispatchNetworkService.getOrderDispatchHistoryByWorkIdsAndNetworkId(network.getId(), orderDispatchNetworkVo.getWorkIds());
        // 查询是否存在派工的历史工单，仅内部网点才执行
        List<ZjWorkDispatchEngineer> workDispatchEngineerList = null;
        if (network.getCategory() == NetworkConstant.CATEGORY_1 && null != orderDispatchNetworkVo.getNetworkEmpId() && orderDispatchNetworkVo.getNetworkEmpId() > 0) {
            workDispatchEngineerList = workDispatchEngineerService.getByNetworkEmpIdAndWorkIds(network.getId(), orderDispatchNetworkVo.getNetworkEmpId(), orderDispatchNetworkVo.getWorkIds());
        }
        List<ZjWorkOrder> workOrders = new ArrayList<>();
        List<ZjWorkDetail> workDetails = new ArrayList<>();
        List<ZjWorkDispatchNetwork> addDispatchNetwork = new ArrayList<>();
        List<ZjWorkDispatchNetwork> updateDispatchNetwork = new ArrayList<>();
        List<ZjWorkDispatchEngineer> addDispatchEngineerList = new ArrayList<>();
        List<ZjWorkDispatchEngineer> updateDispatchEngineerList = new ArrayList<>();
        List<WorkLogVo> serviceEmpLogs = new ArrayList<>(); // 客服日志对象
        List<WorkLogVo> networkLogs = new ArrayList<>(); // 服务商日志对象
        ZjWorkOrder order = null;
        ZjWorkOrder work = null;
        ZjWorkDetail workDetail = null;
        ZjWorkDispatchNetwork dispatchNetwork = null;
        ZjWorkDispatchEngineer dispatchEngineer = null;
        StringBuilder builder = new StringBuilder();
        for (Long workId : orderDispatchNetworkVo.getWorkIds()) {
            order = new ZjWorkOrder();
            order.setId(workId);
            order.setNetworkId(orderDispatchNetworkVo.getNetworkId());
            order.setNetworkEmpId(orderDispatchNetworkVo.getNetworkEmpId());
            order.setStatus(network.getCategory() == NetworkConstant.CATEGORY_2? WorkConstant.WORK_STATUS_2 : networkSureReceiveOrder || dispatchEngineerFlag? WorkConstant.WORK_STATUS_3 : WorkConstant.WORK_STATUS_2);

            work = orderList.stream().filter(f -> Objects.equals(f.getId(), workId)).findFirst().get();
            order.setNetworkModulePrice(work.getNetworkModulePrice());
            order.setUpdateEmpId(loginInfo.getId());
            order.setUpdateEmp(loginInfo.getName());
            workOrders.add(order);

            workDetail = new ZjWorkDetail();
            workDetail.setId(workId);
            workDetail.setDispatchEmpId(loginInfo.getId());
            workDetail.setDispatchTime(new Date());
            workDetails.add(workDetail);
            serviceEmpLogs.add(new WorkLogVo(loginInfo, workId, "工单客服分派服务商", "服务商【" + network.getName() + "】，待确认接单"));

            // 派单服务商
            dispatchNetwork = workDispatchNetworkList.stream().filter(f -> Objects.equals(f.getWorkId(), workId)).findFirst().orElse(null);
            if (null != dispatchNetwork) {
                dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_1);
                dispatchNetwork.setTransferOrderWaitCheck(false);
                dispatchNetwork.setDispatchTime(new Date());
                dispatchNetwork.setRemark(orderDispatchNetworkVo.getRemark());
                updateDispatchNetwork.add(dispatchNetwork);
            } else {
                dispatchNetwork = new ZjWorkDispatchNetwork();
                dispatchNetwork.setId(IdWorker.getId());
                dispatchNetwork.setCustAccId(loginInfo.getCustAccId());
                dispatchNetwork.setWorkId(workId);
                dispatchNetwork.setNetworkId(orderDispatchNetworkVo.getNetworkId());
                dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_1);
                dispatchNetwork.setTransferOrderWaitCheck(false);
                dispatchNetwork.setDispatchTime(new Date());
                dispatchNetwork.setRemark(orderDispatchNetworkVo.getRemark());
                addDispatchNetwork.add(dispatchNetwork);
            }
            // 派工工程师
            if (network.getCategory() == NetworkConstant.CATEGORY_1) {
                if (dispatchEngineerFlag) {
                    builder.delete(0, builder.length()); // 清空内容
                    builder.append(networkSureReceiveOrder? "服务商已确认接单" : "服务商已自动确认接单")
                            .append("，并指派工程师，等待工程师确认接单");
                    networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), network.getName(), workId, "派服务商确认接单并派工", builder.toString()));

                    dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_3);
                    dispatchNetwork.setReceivingOrderTime(new Date());

                    dispatchEngineer = workDispatchEngineerList.stream().filter(f -> Objects.equals(f.getWorkId(), workId)).findFirst().orElse(null);
                    if (null != dispatchEngineer) {
                        dispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_1);
                        dispatchEngineer.setDispatchTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                        dispatchEngineer.setDispatchRemark(orderDispatchNetworkVo.getRemark());
                        dispatchEngineer.setReservation(false);
                        dispatchEngineer.setReservationDate("");
                        dispatchEngineer.setReservationStartTime("");
                        dispatchEngineer.setReservationEndTime("");
                        dispatchEngineer.setNetworkEmpFinishTime("");
                        dispatchEngineer.setRemark("");
                        dispatchEngineer.setCallPhoneQty(0);
                        dispatchEngineer.setCallPhoneTime("");
                        dispatchEngineer.setWriteCallPhoneResult(false);
                        dispatchEngineer.setSignIn(false);
                        // 工程师自动确认接单
                        setNetworkEngingerAutoSureReceiveOrder(networkEngingerSureReceiveOrder, loginInfo.getCustAccId(), empDetailView.getAccountName(), workId, networkLogs, dispatchEngineer, dispatchNetwork);
                        updateDispatchEngineerList.add(dispatchEngineer);
                    } else {
                        dispatchEngineer = new ZjWorkDispatchEngineer();
                        dispatchEngineer.setId(IdWorker.getId());
                        dispatchEngineer.setCustAccId(loginInfo.getCustAccId());
                        dispatchEngineer.setWorkId(workId);
                        dispatchEngineer.setNetworkId(orderDispatchNetworkVo.getNetworkId());
                        dispatchEngineer.setNetworkEmpId(orderDispatchNetworkVo.getNetworkEmpId());
                        dispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_1);
                        dispatchEngineer.setDispatchTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                        dispatchEngineer.setDispatchRemark(orderDispatchNetworkVo.getRemark());
                        dispatchEngineer.setReservation(false);
                        dispatchEngineer.setReservationDate("");
                        dispatchEngineer.setReservationStartTime("");
                        dispatchEngineer.setReservationEndTime("");
                        dispatchEngineer.setNetworkEmpFinishTime("");
                        dispatchEngineer.setRemark("");
                        dispatchEngineer.setCallPhoneQty(0);
                        dispatchEngineer.setCallPhoneTime("");
                        dispatchEngineer.setWriteCallPhoneResult(false);
                        dispatchEngineer.setSignIn(false);
                        // 工程师自动确认接单
                        setNetworkEngingerAutoSureReceiveOrder(networkEngingerSureReceiveOrder, loginInfo.getCustAccId(), empDetailView.getAccountName(), workId, networkLogs, dispatchEngineer, dispatchNetwork);
                        addDispatchEngineerList.add(dispatchEngineer);
                    }
                } else {
                    if (networkSureReceiveOrder) {
                        dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_2);
                        dispatchNetwork.setReceivingOrderTime(new Date());
                        networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), network.getName(), workId, "服务商已自动确认接单，待派工"));
                    }
                }
            }
        }
        workOrderService.updateBatchById(workOrders);
        if (CollectionUtil.isNotEmpty(workDetails)) workDetailService.updateBatchById(workDetails);
        if (CollectionUtil.isNotEmpty(addDispatchNetwork)) workDispatchNetworkService.saveBatch(addDispatchNetwork);
        workDispatchNetworkService.updateRepeatDispatchOrderById(updateDispatchNetwork);
        if (CollectionUtil.isNotEmpty(addDispatchEngineerList)) workDispatchEngineerService.saveBatch(addDispatchEngineerList);
        if (CollectionUtil.isNotEmpty(updateDispatchEngineerList)) workDispatchEngineerService.updateBatchById(updateDispatchEngineerList);
        WorkServiceLog.saveService(serviceEmpLogs);
        WorkServiceLog.saveNetwork(networkLogs);
        if (dispatchEngineerFlag && !networkEngingerSureReceiveOrder){
            try {
                new EngineerReceiveTimeoutJob(dispatchEngineer.getCustAccId(), dispatchEngineer.getId(), dispatchNetwork.getId());
            } catch (SchedulerException e) {
                throw new RuntimeException("创建工程师超时未接单任务失败", e);
            }
        }else {
            if (networkSureReceiveOrder) {
                try {
                    new NetworkDispatchTimeoutJob(dispatchNetwork.getCustAccId(), dispatchNetwork.getId());
                } catch (SchedulerException e) {
                    throw new RuntimeException("创建服务商超时未派单任务失败",e);
                }
            }else {
                try {
                    new NetworkReceiveTimeoutJob(dispatchNetwork.getCustAccId(), dispatchNetwork.getId());
                } catch (SchedulerException e) {
                    throw new RuntimeException("创建服务商超时未接单任务失败", e);
                }
            }
        }
        // 事务提交后发送短信
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                // 发送短信
                SmsSendMessageService.sendNewOrder(loginInfo, WorkUtilService.getOrderReceive(orderDispatchNetworkVo.getWorkIds()));
            }
        });
    }

    /**
     * 设置工单师自动确认接单数据
     * @param networkEngingerSureReceiveOrder
     * @param custAccId
     * @param networkEmp
     * @param workId
     * @param networkLogs
     * @param dispatchEngineer
     * @param dispatchNetwork
     */
    private void setNetworkEngingerAutoSureReceiveOrder( boolean networkEngingerSureReceiveOrder, Long custAccId, String networkEmp, Long workId, List<WorkLogVo> networkLogs,
                                                         ZjWorkDispatchEngineer dispatchEngineer, ZjWorkDispatchNetwork dispatchNetwork) {
        if (!networkEngingerSureReceiveOrder) {
            dispatchEngineer.setReceivingOrderTime("");
            return;
        }
        dispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_2);
        dispatchEngineer.setReceivingOrderTime(ZbDateConvertUtil.dateToDateStr(new Date()));
        networkLogs.add(new WorkLogVo(custAccId, networkEmp, workId, "工程师已自动确认接单"));
        dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_4);
    }

    // 改派服务商
    @Override
    @Transactional
    public void changeNetwork(AccounLoginInfo loginInfo, OrderChangeNetworkVo changeNetworkVo) {
        Assert.isTrue(!Objects.equals(changeNetworkVo.getCurrentNetworkId(), changeNetworkVo.getChangeToNetworkId()), "当前服务商与改派后的服务商是相同服务商，不可改派");
        ZjWorkOrder order = workOrderService.getById(changeNetworkVo.getWorkId());
        Assert.notNull(order, "工单数据不存在");
        Assert.isTrue(order.getStatus() == WorkConstant.WORK_STATUS_2 || order.getStatus() == WorkConstant.WORK_STATUS_3,
                "该工单流程状态处于非[待服务商确认 或 处理中]，不可改派服务商");
        Assert.isTrue(Objects.equals(order.getNetworkId(), changeNetworkVo.getCurrentNetworkId()), "改派前的服务商参数与工单当前的服务不匹配，改派前的服务商与工单原服务商必须匹配");
        workOrderService.checkOrderEvent(changeNetworkVo.getWorkId());

        ZjNetwork oldNetwork = networkService.getById(changeNetworkVo.getCurrentNetworkId());
        Assert.isTrue(null != oldNetwork, "当前服务商ID参数["+ changeNetworkVo.getCurrentNetworkId() +"]的服务商数据不存在");

        ZjNetwork network = networkService.getById(changeNetworkVo.getChangeToNetworkId());
        Assert.isTrue(null != network, "改派服务商ID参数["+ changeNetworkVo.getChangeToNetworkId() +"]的服务商数据不存在");

        // todo 外部服务商发送改派申请
        if (oldNetwork.getCategory() == NetworkConstant.CATEGORY_2) {

        }
        ZjWorkReassign reassign = new ZjWorkReassign();
        reassign.setId(IdWorker.getId());
        reassign.setCustAccId(loginInfo.getCustAccId());
        reassign.setWorkId(changeNetworkVo.getWorkId());
        reassign.setCurrentNetworkId(changeNetworkVo.getCurrentNetworkId());
        reassign.setChangeToNetworkId(changeNetworkVo.getChangeToNetworkId());
        reassign.setStatus(oldNetwork.getCategory() == NetworkConstant.CATEGORY_2? WorkConstant.WORK_REASSIGN_STATUS_1 : WorkConstant.WORK_REASSIGN_STATUS_2);
        reassign.setApplyEmpType(WorkConstant.WORK_REASSIGN_EMP_TYPE_1);
        reassign.setApplyEmpId(loginInfo.getId());
        reassign.setApplyEmp(loginInfo.getName());
        reassign.setApplyRemark(changeNetworkVo.getRemark());
        reassign.setReviewEmpType(oldNetwork.getCategory() == NetworkConstant.CATEGORY_2? 0 : WorkConstant.WORK_REASSIGN_EMP_TYPE_1);
        reassign.setReviewEmpId(oldNetwork.getCategory() == NetworkConstant.CATEGORY_2? 0L : loginInfo.getId());
        reassign.setReviewEmp(oldNetwork.getCategory() == NetworkConstant.CATEGORY_2? "" : loginInfo.getName());
        reassign.setReviewRemark("");
        reassign.setCancelRemark("");
        workReassignService.save(reassign);

        List<WorkLogVo> serviceEmpLogs = new ArrayList<>(); // 客服日志对象
        List<WorkLogVo> networkLogs = new ArrayList<>(); // 服务商日志对象
        serviceEmpLogs.add(new WorkLogVo(loginInfo, changeNetworkVo.getWorkId(), "申请改派服务商，等待服务商审核", "备注：" + changeNetworkVo.getRemark()));
        if (oldNetwork.getCategory() == NetworkConstant.CATEGORY_2) {
            // todo 待对接第三方服务商
            WorkServiceLog.saveService(serviceEmpLogs);
            WorkServiceLog.saveNetwork(networkLogs);
            return;
        }
        networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), oldNetwork.getName(), changeNetworkVo.getWorkId(), "改派服务商申请，审核已通过"));
        dispatchOrderToNetwork(loginInfo, changeNetworkVo.getChangeToNetworkEmpId(), changeNetworkVo.getRemark(), order, network, serviceEmpLogs, networkLogs);
        WorkServiceLog.saveService(serviceEmpLogs);
        WorkServiceLog.saveNetwork(networkLogs);
        // 事务提交成功后发送短信
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                // 发送短信
                SmsSendMessageService.sendNewOrder(loginInfo, WorkUtilService.getOrderReceive(order.getId()));
            }
        });
    }

    /**
     * 工单派单给服务商
     * @param loginInfo
     * @param newNetworkEmpId
     * @param remark
     * @param order
     * @param newNetwork
     * @param serviceEmpLogs
     * @param networkLogs
     */
    private void dispatchOrderToNetwork(AccounLoginInfo loginInfo, Long newNetworkEmpId, String remark, ZjWorkOrder order, ZjNetwork newNetwork, List<WorkLogVo> serviceEmpLogs, List<WorkLogVo> networkLogs) {
        boolean dispatchEngineerFlag = null != newNetworkEmpId && newNetworkEmpId > 0; // 是否指定工程师
        boolean networkInnerService = newNetwork.getCategory() == NetworkConstant.CATEGORY_1; // 是否内部服务商
        boolean networkSureReceiveOrder = false; // 服务商自动确认接单，仅内部服务商
        boolean networkEngingerSureReceiveOrder = false; // 工程师自动确认接单，仅内部工程师
        if (networkInnerService) {
            ZjNetworkStrategy sureReceiveOrder = networkStrategyService.isAutoSureReceiveOrder(newNetwork.getId());
            networkSureReceiveOrder = sureReceiveOrder.getAutoSureReceiveOrder();
            networkEngingerSureReceiveOrder = networkEmpService.isAutoSureReceiveOrderById(newNetworkEmpId);
        }

        serviceEmpLogs.add(new WorkLogVo(loginInfo, order.getId(),  "改派服务商审核通过，正在派单给新服务商"));
        serviceEmpLogs.add(new WorkLogVo(loginInfo, order.getId(), "重新派单成功，等待新服务商确认接单"));

        ZjNetworkModuleSettlement networkModuleSettlement = networkModuleSettlementService.getNetworkIdAndModuleId(newNetwork.getId(), order.getModuleId());
        ZjWorkDispatchNetwork dispatchNetwork = workDispatchNetworkService.getByWorkId(order.getId());
        ZjWorkDispatchEngineer dispatchEngineer = workDispatchEngineerService.getByWorkIdAndNetworkIdAndNetworkEmpId(order.getId(), order.getNetworkId(), order.getNetworkEmpId());

        ZjWorkOrder workOrder = new ZjWorkOrder();
        workOrder.setId(order.getId());
        workOrder.setStatus(newNetwork.getCategory() == NetworkConstant.CATEGORY_2? WorkConstant.WORK_STATUS_2 : networkSureReceiveOrder || dispatchEngineerFlag? WorkConstant.WORK_STATUS_3 : WorkConstant.WORK_STATUS_2);
        workOrder.setNetworkId(newNetwork.getId());
        workOrder.setNetworkEmpId(newNetworkEmpId);
        workOrder.setNetworkModulePrice(null != networkModuleSettlement? networkModuleSettlement.getPrice() : new BigDecimal("0.00"));
        workOrder.setChangeOrder(true);
        workOrder.setNewAdvance(0);
        workOrder.setWaitCopeEvent(0);
        workOrder.setUpdateEmpId(loginInfo.getId());
        workOrder.setUpdateEmp(loginInfo.getName());
        workOrderService.updateById(workOrder);

        ZjWorkDetail workDetail = new ZjWorkDetail();
        workDetail.setId(order.getId());
        workDetail.setDispatchEmpId(loginInfo.getId());
        workDetail.setDispatchTime(new Date());
        workDetail.setReservation(false);
        workDetail.setReservationDate(null);
        workDetail.setReservationStartTime(null);
        workDetail.setReservationEndTime(null);
        workDetailService.updateById(workDetail);

        // 更改旧服务商信息
        ZjWorkDispatchNetwork oldDispatchNetwork = new ZjWorkDispatchNetwork();
        oldDispatchNetwork.setId(dispatchNetwork.getId());
        oldDispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_9);
        oldDispatchNetwork.setChangeTime(new Date());
        workDispatchNetworkService.updateById(oldDispatchNetwork);

        ZjWorkDispatchNetwork newDispatchNetwork = new ZjWorkDispatchNetwork();
        newDispatchNetwork.setCustAccId(loginInfo.getCustAccId());
        newDispatchNetwork.setWorkId(order.getId());
        newDispatchNetwork.setNetworkId(newNetwork.getId());
        newDispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_1);
        newDispatchNetwork.setTransferOrderWaitCheck(false);
        newDispatchNetwork.setDispatchTime(new Date());
        newDispatchNetwork.setRemark(remark);


        List<ZjWorkDispatchEngineer> addEngineerList = new ArrayList<>();
        List<ZjWorkDispatchEngineer> updateEngineerList = new ArrayList<>();

        // 更改旧工程师信息
        if (null != dispatchEngineer) {
            ZjWorkDispatchEngineer oldDispatchEngineer = new ZjWorkDispatchEngineer();
            oldDispatchEngineer.setId(dispatchEngineer.getId());
            oldDispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_8);
            updateEngineerList.add(oldDispatchEngineer);
        }
        ZjWorkDispatchEngineer newDispatchEngineer = new ZjWorkDispatchEngineer();
        if (newNetwork.getCategory() == NetworkConstant.CATEGORY_2) {
            // todo 派单到第三方服务商
        } else {
            if (dispatchEngineerFlag) {
                ViewNetworkEmpDetail empDetailView = viewNetworkEmpDetailService.getByNetworkIdAndNetworkEmpId(newNetwork.getId(), newNetworkEmpId);
                networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), newNetwork.getName(), order.getId(), "新服务商确认接单并派工", "服务商指派工程师【" + empDetailView.getAccountName() + "】，待工程师接单"));

                newDispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_3);
                newDispatchNetwork.setReceivingOrderTime(new Date());

                ZjWorkDispatchEngineer dispatchEngineer2 = workDispatchEngineerService.getByWorkIdAndNetworkIdAndNetworkEmpId(order.getId(), newNetwork.getId(), newNetworkEmpId);
                newDispatchEngineer.setCustAccId(loginInfo.getCustAccId());
                newDispatchEngineer.setWorkId(order.getId());
                newDispatchEngineer.setNetworkId(newNetwork.getId());
                newDispatchEngineer.setNetworkEmpId(newNetworkEmpId);
                newDispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_1);
                newDispatchEngineer.setDispatchTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                newDispatchEngineer.setReceivingOrderTime("");
                newDispatchEngineer.setDispatchRemark("");
                newDispatchEngineer.setReservation(false);
                newDispatchEngineer.setReservationDate("");
                newDispatchEngineer.setReservationStartTime("");
                newDispatchEngineer.setReservationEndTime("");
                newDispatchEngineer.setNetworkEmpFinishTime("");
                newDispatchEngineer.setRemark("");
                newDispatchEngineer.setCallPhoneQty(0);
                newDispatchEngineer.setCallPhoneTime("");
                newDispatchEngineer.setWriteCallPhoneResult(false);
                newDispatchEngineer.setSignIn(false);
                if (networkEngingerSureReceiveOrder) {
                    newDispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_2);
                    newDispatchEngineer.setReceivingOrderTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                    newDispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_4);
                    networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), empDetailView.getAccountName(), order.getId(), "工程师自动接单"));
                }
                if (null == dispatchEngineer2) {
                    newDispatchEngineer.setId(IdWorker.getId());
                    addEngineerList.add(newDispatchEngineer);
                } else {
                    newDispatchEngineer.setId(dispatchEngineer2.getId());
                    updateEngineerList.add(newDispatchEngineer);
                }
            } else {
                if (networkSureReceiveOrder) {
                    newDispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_2);
                    newDispatchNetwork.setReceivingOrderTime(new Date());
                    networkLogs.add(new WorkLogVo(loginInfo.getCustAccId(), newNetwork.getName(), order.getId(), "服务商已自动确认接单，待派工"));
                }
            }
        }
        if (CollectionUtil.isNotEmpty(addEngineerList)) workDispatchEngineerService.saveBatch(addEngineerList);
        if (CollectionUtil.isNotEmpty(updateEngineerList)) workDispatchEngineerService.updateBatchById(updateEngineerList);

        ZjWorkDispatchNetwork dispatchNetwork2 = workDispatchNetworkService.getByWorkIdAndNetowrkId(order.getId(), newNetwork.getId());
        if (null == dispatchNetwork2) {
            newDispatchNetwork.setId(IdWorker.getId());
            workDispatchNetworkService.save(newDispatchNetwork);
        } else {
            newDispatchNetwork.setId(dispatchNetwork2.getId());
            workDispatchNetworkService.updateRepeatDispatchOrderById(newDispatchNetwork);
        }

        if (dispatchEngineerFlag && !networkEngingerSureReceiveOrder){
            try {
                new EngineerReceiveTimeoutJob(newDispatchEngineer.getCustAccId(), newDispatchEngineer.getId(), newDispatchNetwork.getId());
            } catch (SchedulerException e) {
                throw new RuntimeException("创建工程师超时未接单任务失败", e);
            }
        }else {
            if (networkSureReceiveOrder){
                try {
                    new NetworkDispatchTimeoutJob(newDispatchNetwork.getCustAccId(), newDispatchNetwork.getId());
                } catch (SchedulerException e) {
                    throw new RuntimeException("创建服务商超时未派单任务失败",e);
                }
            }else {
                try {
                    new NetworkReceiveTimeoutJob(newDispatchNetwork.getCustAccId(), newDispatchNetwork.getId());
                } catch (SchedulerException e) {
                    throw new RuntimeException("创建服务商超时未接单任务失败", e);
                }
            }
        }
    }

    // 改派工单客服
    @Override
    @Transactional
    public void changeServiceEmp(AccounLoginInfo loginInfo, OrderChangeServiceEmpVo changeServiceEmpVo) {
        ZjWorkOrder workOrder = workOrderService.getById(changeServiceEmpVo.getWorkId());
        Assert.isTrue(null != workOrder, "工单ID参数["+ changeServiceEmpVo.getWorkId() +"]的工单数据不存在");
        workOrderService.checkOrderStatus(changeServiceEmpVo.getWorkId());
        Assert.isTrue(!Objects.equals(workOrder.getEmpId(), changeServiceEmpVo.getEmpId()), "当前客服与改派后的工单客服相同，同一个工单客服不可重复改派");

        ZjAccount account = accountService.getById(changeServiceEmpVo.getEmpId());
        Assert.isTrue(null != account, "改派的工单客服，在系统中不存在该客服数据");

        ZjWorkOrder order = new ZjWorkOrder();
        order.setId(workOrder.getId());
        order.setAssignEmp(true);
        order.setEmpId(changeServiceEmpVo.getEmpId());
        order.setAssignEmpTime(new Date());
        order.setUpdateEmpId(loginInfo.getId());
        order.setUpdateEmp(loginInfo.getName());
        workOrderService.updateById(order);
        workEmpChangeLogService.save(loginInfo.getCustAccId(), workOrder.getEmpId(), changeServiceEmpVo);
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, workOrder.getId(), "改派工单客服成功","新客服：" + account.getName() + "；备注：" + changeServiceEmpVo.getRemark()));
    }

    // 保存工单留言
    @Override
    @Transactional
    public void saveWorkLeaveMessage(AccounLoginInfo loginInfo, OrderLeaveMessageVo orderLeaveMessageVo) {
        ZjWorkOrder workOrder = workOrderService.getById(orderLeaveMessageVo.getWorkId());
        Assert.isTrue(null != workOrder, "工单ID参数["+ orderLeaveMessageVo.getWorkId() +"]的工单数据不存在");
        //PC不检查工单状态直接可以留言
        //workOrderService.checkOrderStatus(workOrder.getId());
        List<OrderLeaveMessage> messageList = new ArrayList<>();
        for (Integer visitType : orderLeaveMessageVo.getVisitTypes()) {
            messageList.add(new OrderLeaveMessage()
                    .setCustAccId(workOrder.getCustAccId())
                    .setWorkId(orderLeaveMessageVo.getWorkId())
                    .setWorkNo(workOrder.getCode())
                    .setVisitType(visitType)
                    .setEmpType(1)
                    .setEmpId(loginInfo.getId())
                    .setEmp(loginInfo.getName())
                    .setContent(null == orderLeaveMessageVo.getContent() ? "" : orderLeaveMessageVo.getContent())
                    .setAnnexs(orderLeaveMessageVo.getAnnex())
            );
        }
        workLeaveMessageService.save(messageList);
    }

    // 保存服务商的工单留言
    @Override
    @Transactional
    public void saveNetworkWorkLeaveMessage(AccounLoginInfo loginInfo, OrderLeaveMessageVo orderLeaveMessageVo) {
        ZjNetworkEmpRelation empRelation = networkEmpRelationService.getNetworkEmpIdAndNetworkId(loginInfo.getNetworkEmpId(), loginInfo.getNetworkId());
        // 判断是否为工程师
        boolean manager = null != empRelation && (empRelation.getManager() || empRelation.getSuperManager());
        if (!manager) {
            // 校验工单是否转单或转单待审核
            boolean hasWaitOrder = workChangeEngineerService.isApplyChangeEngineerWaitCheck(orderLeaveMessageVo.getWorkId());
            Assert.isFalse(hasWaitOrder, "当前工单已申请转单待审核中，禁止操作");
        }
        ZjWorkOrder workOrder = workOrderService.getById(orderLeaveMessageVo.getWorkId());
        Assert.isTrue(null != workOrder, "工单ID参数["+ orderLeaveMessageVo.getWorkId() +"]的工单数据不存在");
        //手机端不检查工单状态直接可以留言
        //workOrderService.checkOrderStatus(workOrder.getId());
        boolean engineer = null != workOrder.getNetworkEmpId() && Objects.equals(workOrder.getNetworkEmpId(), loginInfo.getNetworkEmpId());
        if (engineer) {
            List<OrderLeaveMessage> messageList = setOrderLeaveMessageData(loginInfo, workOrder, 3, orderLeaveMessageVo);
            workLeaveMessageService.save(messageList);
            return;
        }
        List<OrderLeaveMessage> messageList = setOrderLeaveMessageData(loginInfo, workOrder, 2, orderLeaveMessageVo);
        workLeaveMessageService.save(messageList);
    }

    /**
     * 设置留言数据
     * @param loginInfo
     * @param workOrder
     * @param empType 操作人员类型：1-客服，2-服务商，3-工程师，4-工单客户
     * @param orderLeaveMessageVo
     * @return
     */
    private List<OrderLeaveMessage> setOrderLeaveMessageData(AccounLoginInfo loginInfo, ZjWorkOrder workOrder, Integer empType, OrderLeaveMessageVo orderLeaveMessageVo) {
        List<OrderLeaveMessage> messageList = new ArrayList<>();
        for (Integer visitType : orderLeaveMessageVo.getVisitTypes()) {
            messageList.add(new OrderLeaveMessage()
                    .setCustAccId(workOrder.getCustAccId())
                    .setWorkId(orderLeaveMessageVo.getWorkId())
                    .setWorkNo(workOrder.getCode())
                    .setVisitType(visitType)
                    .setEmpType(empType)
                    .setEmpId(loginInfo.getId())
                    .setEmp(loginInfo.getName())
                    .setContent(null == orderLeaveMessageVo.getContent() ? "" : orderLeaveMessageVo.getContent())
                    .setAnnexs(orderLeaveMessageVo.getAnnex())
            );
        }
        return messageList;
    }

    // 根据工单ID获取客服工单留言
    @Override
    public Map<String, Object> getWorkLeaveMessageList(Long workId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        long count = workLeaveMessageService.getWorkLeaveMessageListCount(workId);
        if (count <= 0) {
            return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), count, new ArrayList<>());
        }
        List<ZjWorkLeaveMessage> messages = workLeaveMessageService.getWorkLeaveMessageList(workId, pageUtil);
        List<Long> empIds = messages.stream().filter(f -> f.getEmpType() == 1 || f.getEmpType() == 2 || f.getEmpType() == 3).map(ZjWorkLeaveMessage::getEmpId).distinct().toList();
        List<Long> userIds = messages.stream().filter(f -> f.getEmpType() == 4).map(ZjWorkLeaveMessage::getEmpId).distinct().toList();
        List<ZjAccount> accountList = new ArrayList<>();
        List<ZjUser> userList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(empIds)) {
            accountList.addAll(accountService.getByIds(empIds));
        }
        if (CollectionUtil.isNotEmpty(userIds)) {
            QueryWrapper<ZjUser> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.select("id", "avatar");
            userList.addAll(userService.list(userQueryWrapper));
        }
        List<ZjWorkLeaveMessageAnnex> messageAnnexList = workLeaveMessageAnnexService.getByWorkId(workId);
        List<WorkLeaveMessageListVo> voList = messages.stream().map(m -> {
            WorkLeaveMessageListVo vo = new WorkLeaveMessageListVo();
            BeanUtil.copyProperties(m, vo);
            vo.setCreateTime(m.getGmtCreate());
            if (m.getEmpType() ==1 || m.getEmpType() == 2 || m.getEmpType() == 3) {
                accountList.stream().filter(f -> Objects.equals(f.getId(), m.getEmpId())).findFirst().ifPresent(o -> vo.setAvatar(o.getAvatar()));
            }
            if (m.getEmpType() == 4) {
                userList.stream().filter(f -> Objects.equals(f.getId(), m.getEmpId())).findFirst().ifPresent(o -> vo.setAvatar(o.getAvatar()));
            }
            vo.setAnnexs(messageAnnexList.stream().filter(f -> Objects.equals(f.getWorkLeaveMessageId(), m.getId())).map(ZjWorkLeaveMessageAnnex::getPath).toList());
            return vo;
        }).toList();
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), count, voList);
    }

    // 根据工单ID获取服务商地址
    @Override
    public SelectAddressVo getOrderNetworkAddress(Long workId) {
        SelectAddressVo addressVo = new SelectAddressVo();
        ZjWorkOrder order = workOrderService.getById(workId);
        if (null == order) {
            return addressVo;
        }
        ZjNetwork network = networkService.getById(order.getNetworkId());
        if (null == network) {
            return addressVo;
        }
        ViewNetworkEmpDetail empDetailView = viewNetworkEmpDetailService.getManagerByNetworkId(network.getId());
        BeanUtil.copyProperties(network, addressVo);
        addressVo.setPhone(empDetailView.getAccountPhone());
        return addressVo;
    }

    // 工单归档
    @Override
    @Transactional
    public void orderArchived(AccounLoginInfo loginInfo, OrderArchivedVo archivedVo) {
        Assert.notEmpty(archivedVo.getWorkIds(), "归档的工单不能为空，至少要选择一条工单");
        QueryWrapper<ZjWorkOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id", "code", "status", "is_archived AS archived")
                .in("id", archivedVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(wrapper);
        List<String> workIds = archivedVo.getWorkIds().stream().filter(f -> orderList.stream().noneMatch(f2 -> Objects.equals(f2.getId(), f))).map(Object::toString).distinct().toList();
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "归档的工单数据不存在："+ String.join("、", workIds));
        List<String> orderNos = orderList.stream().filter(f -> !Objects.equals(WorkConstant.WORK_STATUS_4, f.getStatus()) && !Objects.equals(WorkConstant.WORK_STATUS_5, f.getStatus()))
                .map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(orderNos), "工单流程未完成或未取消，正在处理或处理中，禁止归档："+String.join("、", orderNos));
        orderNos = orderList.stream().filter(ZjWorkOrder::getArchived).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(orderNos), "工单流程未完成或未取消，正在处理或处理中，禁止归档："+String.join("、", orderNos));

        List<ZjWorkOrder> updateOrders = new ArrayList<>();
        ZjWorkOrder order = null;
        List<WorkLogVo> logVos = new ArrayList<>();
        for (Long id : archivedVo.getWorkIds()) {
            order = new ZjWorkOrder();
            order.setId(id);
            order.setArchived(true);
            order.setArchivedTime(new Date());
            order.setUpdateEmpId(loginInfo.getId());
            order.setUpdateEmp(loginInfo.getName());
            updateOrders.add(order);
            logVos.add(new WorkLogVo(loginInfo, id, "工单归档", archivedVo.getRemark()));
        }
        workOrderService.updateBatchById(updateOrders);
        WorkServiceLog.saveService(logVos);
    }

    // 获取工单详情的工单费用
    @Override
    public Object getOrderTotalFee(Long workId) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Map<String, Object> resultMap = new HashMap<>();
        if (null == order) {
            return resultMap;
        }
        // 工单服务费
        ZjWorkFeeDetail orderSettlementFees =  workFeeDetailService.getOrderSettlementFeeByWorkId(workId);
        // 工单配件费
        ZjWorkSpareMaterial spareMaterial = workSpareMaterialService.getOrderSettlementFeeByWorkId(workId);
        // 品牌商家结算
        BigDecimal factoryFeeSettlementModulePrice = order.getModulePrice().subtract(order.getFactorySettlementDeductionPrice());
        BigDecimal spareFee = null != spareMaterial? spareMaterial.getReceiveFactoryPrice() : new BigDecimal("0.0");
        BigDecimal serviceFee = null != orderSettlementFees? orderSettlementFees.getReceiveFactoryPrice() : new BigDecimal("0.0");
        if (factoryFeeSettlementModulePrice.floatValue() <= 0) {
            spareFee = spareFee.floatValue() == 0? factoryFeeSettlementModulePrice : spareFee.add(factoryFeeSettlementModulePrice);
        }
        if (spareFee.floatValue() <= 0) {
            serviceFee = serviceFee.longValue() == 0? spareFee : serviceFee.add(spareFee);
        }
        resultMap.put("factoryFeeSettlement", new WorkDetailFeeVo(order.getAllInclusiveFee(),
                factoryFeeSettlementModulePrice.floatValue() < 0? new BigDecimal("0.00") : factoryFeeSettlementModulePrice,
                serviceFee.floatValue() < 0? new BigDecimal("0.00") : serviceFee,
                spareFee.floatValue() < 0? new BigDecimal("0.00") : spareFee
                )
        );
        // 服务商结算
        BigDecimal networkFeeSettlementModulePrice = order.getNetworkModulePrice().subtract(order.getNetworkSettlementDeductionPrice());
        BigDecimal networkSpareFee = null != spareMaterial? spareMaterial.getPayNetworkPrice() : new BigDecimal("0.0");
        BigDecimal networkServiceFee = null != orderSettlementFees? orderSettlementFees.getPayNetworkPrice() : new BigDecimal("0.0");
        if (networkFeeSettlementModulePrice.floatValue() <= 0) {
            networkSpareFee = networkSpareFee.floatValue() == 0? networkFeeSettlementModulePrice : networkSpareFee.add(networkFeeSettlementModulePrice);
        }
        if (networkSpareFee.floatValue() <= 0) {
            networkServiceFee = networkServiceFee.floatValue() == 0? networkSpareFee : networkServiceFee.add(networkSpareFee);
        }
        resultMap.put("networkFeeSettlement", new WorkDetailFeeVo(
                networkFeeSettlementModulePrice.floatValue() < 0 ? new BigDecimal("0.00") : networkFeeSettlementModulePrice,
                networkServiceFee.floatValue() < 0 ? new BigDecimal("0.00") : networkServiceFee,
                networkSpareFee.floatValue() < 0 ? new BigDecimal("0.00") : networkSpareFee
        ));
        // 工程师结算
        resultMap.put("engineerFeeSettlement", new WorkDetailFeeVo());
        // 平台承担
        resultMap.put("platformFeeSettlement", new WorkDetailFeeVo(
                        order.getAllInclusiveFee(), new BigDecimal("0.0"),
                       null != orderSettlementFees? orderSettlementFees.getPrice() : new BigDecimal("0.0"),
                       null != spareMaterial? spareMaterial.getPrice() : new BigDecimal("0.0")
                )
        );
        // 收取客户费用
        resultMap.put("collectCustomerPrice", new WorkDetailFeeVo(order.getCollectCustomerPrice(), new BigDecimal("0.00")));
        return resultMap;
    }


    // 根据工单ID获取是否开启签到
    @Override
    public Object getNetworkEmpIsEnableSign(Long workId) {
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("module_id")
                .eq("id" , workId);
        ZjWorkOrder order = workOrderService.getOne(orderQueryWrapper);
        Assert.notNull(order, "工单参数[ " + workId + " ]的数据不存在");

        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("is_enable_sign AS enableSign")
                .eq("id", order.getModuleId());
        ZjWorkModule module = workModuleService.getOne(moduleQueryWrapper);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("enableSign", module.getEnableSign());
        return resultMap;
    }

    // 根据工单ID获取工程师签到设置
    @Override
    public Object getNetworkEmpMobileSignSet(Long workId) {
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select( "module_id")
                .eq("id" , workId);
        ZjWorkOrder order = workOrderService.getOne(orderQueryWrapper);
        Assert.notNull(order, "工单参数[ " + workId + " ]的数据不存在");

        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("is_enable_sign AS enableSign", "sign_type", "sign_range", "sign_range_type", "is_enable_security_watermark AS enableSecurityWatermark")
                .eq("id", order.getModuleId());
        ZjWorkModule module = workModuleService.getOne(moduleQueryWrapper);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("callPhoneType", module.getCallPhoneType()); // 拨打电话类型：0-关闭，1-必须拨打
        resultMap.put("enableSign", module.getEnableSign()); // 是否启用签到：false-不启用，true-启用
        resultMap.put("signType", module.getSignType()); // 签到方式：1-定位签到，2-拍照签到
        resultMap.put("signRangeType", module.getSignRangeType()); // 签到范围限制：1-有限制，2-不限制
        resultMap.put("signRange", module.getSignRange()); // 签到范围，单位：米，当sign_type=1且sign_range_type=1时生效
        resultMap.put("enableSecurityWatermark", module.getEnableSecurityWatermark()); // 是否启用拍照防伪作弊水印：false-不启用，true-启用，当sign_type=2时生效
        return resultMap;
    }

    // 根据工单ID获取结单核销码
    @Override
    @Transactional
    public void getStatementWriteOffCode(AccounLoginInfo loginInfo, Long workId) throws SMSException {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "结单工单参数[ " + workId + " ]的数据不存在，无法发送核销码");

        ZjWorkUser workUser = workUserService.getById(workId);
        // 获取核销码
        ZjWorkModule module = workModuleService.getById(order.getModuleId());
        String code = null;
        if (module.getStatementVerifCodeType() == 2) {
            ZjWorkDetail detail = workDetailService.getById(workId);
            code = detail.getStatementVerifCode();
        } else {
            code = RandomUtil.randomNumber6();
        }
        // 缓存核销码
        SmsVerificCodeService.getWriteOffCode(workUser.getPhone(), code);
        // 发送核销码
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("username", workUser.getName());
        paramMap.put("workNo", order.getCode());
        paramMap.put("code", code);
        SmsSendMessageService.sendNoticeSms(true, loginInfo, SmsCode.WRITE_OFF_CODE.getCode(), workUser.getPhone(), workUser.getName(), paramMap);
        if (module.getStatementVerifCodeType() == 1) {
            // 更新核销码
            ZjWorkDetail updateWorkDetail = new ZjWorkDetail();
            updateWorkDetail.setId(workId);
            updateWorkDetail.setStatementVerifCode(code);
            workDetailService.updateById(updateWorkDetail);
        }
    }

    // 获取核销码
    @Override
    public String getStatementWriteOffCode(Long workId, Long moduleId, String userPhone) {
        ZjWorkModule module = workModuleService.getById(moduleId);
        String code = null;
        if (module.getStatementVerifCodeType() == 2) {
            ZjWorkDetail detail = workDetailService.getById(workId);
            code = detail.getStatementVerifCode();
        } else {
            code = RandomUtil.randomNumber6();
        }
        SmsVerificCodeService.getWriteOffCode(userPhone, code);
        return code;
    }

    // 根据工单ID获取待审核改派服务商的工单
    @Override
    public WorkWaitCheckReassignVo getWaitCheckWorkReassign(Long workId) {
        ZjWorkReassign reassign = workReassignService.getWaitCheckWorkReassign(workId);
        Assert.notNull(reassign, "当前工单没有待审核改派的工单");
        WorkWaitCheckReassignVo vo = new WorkWaitCheckReassignVo();
        BeanUtil.copyProperties(reassign, vo);
        vo.setCreateTime(reassign.getGmtCreate());
        vo.setCurrentNetwork(networkService.getNameById(reassign.getCurrentNetworkId()));
        return vo;
    }

    // 审核改派服务商的工单
    @Override
    @Transactional
    public void checkWorkReassign(AccounLoginInfo loginInfo, Long workId, WorkCheckReassignVo reassignVo) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "改派的工单参数[ " + workId+ " ]的数据不存在");

        ZjWorkReassign reassign = workReassignService.getById(reassignVo.getId());
        Assert.notNull(reassign, "待审核的工单改派参数[ "  + reassignVo.getId() +" ]的数据不存在");

        ZjWorkReassign updateReassign = new ZjWorkReassign();
        updateReassign.setId(reassign.getId());
        updateReassign.setStatus(reassignVo.getCheckTypep() == 1? WorkConstant.WORK_REASSIGN_STATUS_2 : WorkConstant.WORK_REASSIGN_STATUS_3);
        updateReassign.setChangeToNetworkId(reassignVo.getCheckTypep() == 1? reassignVo.getChangeToNetworkId() : 0L);
        updateReassign.setReviewEmpType(WorkConstant.WORK_REASSIGN_EMP_TYPE_1);
        updateReassign.setReviewEmpId(loginInfo.getId());
        updateReassign.setReviewEmp(loginInfo.getName());
        updateReassign.setReviewTime(new Date());
        updateReassign.setReviewRemark(reassignVo.getRemark());
        workReassignService.updateById(updateReassign);

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(workId);
        updateOrder.setWaitCopeEvent(order.getWaitCopeEvent() -1);
        workOrderService.updateById(updateOrder);

        ZjWorkDetail workDetail = new ZjWorkDetail();
        workDetail.setId(workId);
        workDetail.setChangeNetworkApply(false);
        workDetailService.updateById(workDetail);
        // todo 如果为第三方工单，则审核结果需返回
        // 驳回
        if (reassignVo.getCheckTypep() == 2) {
            WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId, "工单改派服务已审核，并且已驳回", reassignVo.getRemark()));
            return;
        }
        ZjNetwork network = networkService.getById(reassignVo.getChangeToNetworkId());
        Assert.notNull(network, "工单改派的新服务商参数[ " + reassignVo.getChangeToNetworkId()+ " ]的数据不存在");
        List<WorkLogVo> serviceEmpLogs = new ArrayList<>();
        List<WorkLogVo> networkLogs = new ArrayList<>();
        dispatchOrderToNetwork(loginInfo, reassignVo.getNetworkEmpId(), reassignVo.getRemark(), order, network, serviceEmpLogs, networkLogs);
        WorkServiceLog.saveService(serviceEmpLogs);
        WorkServiceLog.saveNetwork(networkLogs);
        // 事务提交成功后发送短信
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                // 发送短信
                SmsSendMessageService.sendNewOrder(loginInfo, WorkUtilService.getOrderReceive(order.getId()));
            }
        });
    }

    // 根据工单ID获取工单待结单审核
    @Override
    public WorkWaitCheckFinishOrderVo getWaitCheckStatementOrder(Long workId) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "结单工单参数[ " + workId + " ]的数据不存在");
        ZjWorkFinishOrder finishOrder = workFinishOrderService.getWaitCheckStatementOrder(workId);
        Assert.notNull(finishOrder, "当前工单没有待审核的结单信息");

        WorkWaitCheckFinishOrderVo vo = new WorkWaitCheckFinishOrderVo();
        BeanUtil.copyProperties(finishOrder, vo);
        vo.setApplyTime(finishOrder.getGmtCreate());
        List<WorkFinishOrderTemplateExtend> orderTemplates = workFinishOrderTemplateService.getByWorkFinishOrderId(finishOrder.getId());
        List<WorkFinishOrderTemplateFieldValExtend> extendList = workFinishOrderTemplateFieldValService.getByWorkStatementTemplateIds(orderTemplates.stream().map(WorkFinishOrderTemplateExtend::getId).toList());
        vo.setFinishOrderTemplates(orderTemplates.stream().map(template -> {
            WorkFinishOrderTemplateVo templateVo = new WorkFinishOrderTemplateVo();
            templateVo.setTemplate(template.getTemplate());
            templateVo.setFieldVals(extendList.stream().filter(f -> Objects.equals(f.getWorkFinishOrderTemplateId(), template.getId())).map(fieldVal -> {
                FieldValVo valVo = new FieldValVo();
                valVo.setId(fieldVal.getId());
                valVo.setType(fieldVal.getType());
                valVo.setName(fieldVal.getName());
                valVo.setOptVos(fieldVal.getVals());
                return valVo;
            }).toList());
            return templateVo;
        }).toList());
        return vo;
    }

    // 审核结单
    @Override
    @Transactional
    public void checkStatementOrder(AccounLoginInfo loginInfo, Long workId, WorkCheckStatementVo checkStatementVo) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "系统中查无此结单的工单");
        Assert.isFalse(order.getEndOrder(), "当前工单已结单，禁止重复操作！");

        ZjWorkFinishOrder finishOrder = workFinishOrderService.getById(checkStatementVo.getId());
        Assert.notNull(finishOrder, "当前工单没有结单待审核的事件！");
        ZjWorkDetail workDetail = workDetailService.getById(workId);
        Assert.isTrue(workDetail.getNoReviewApplyWorkFeeNum() <= 0, "当前工单存在未审核的工单费用，不允许结单操作！");
        Assert.isTrue(workDetail.getNoReviewApplyWorkSpareNum() <= 0, "当前工单存在未审核的工单配件，不允许结单操作！");
        // 服务商
        ZjWorkDispatchNetwork dispatchNetwork = workDispatchNetworkService.getByWorkIdAndNetowrkId(workId, order.getNetworkId());
        // 工程师
        ZjWorkDispatchEngineer dispatchEngineer = workDispatchEngineerService.getByWorkIdAndNetworkIdAndNetworkEmpId(workId, order.getNetworkId(), order.getNetworkEmpId());

        ZjWorkFinishOrder updateFinishOrder = new ZjWorkFinishOrder();
        updateFinishOrder.setId(finishOrder.getId());
        updateFinishOrder.setStatus(checkStatementVo.getCheckType() == 1? WorkConstant.WORK_FINISH_ORDER_STATUS_2 : WorkConstant.WORK_FINISH_ORDER_STATUS_3);
        updateFinishOrder.setPrice(checkStatementVo.getPrice());
        updateFinishOrder.setSurePrice(checkStatementVo.getSurePrice());
        updateFinishOrder.setRevieworEmpId(loginInfo.getId());
        updateFinishOrder.setRevieworEmp(loginInfo.getName());
        updateFinishOrder.setReviewTime(new Date());
        updateFinishOrder.setReviewRemark(checkStatementVo.getRemark());
        workFinishOrderService.updateById(updateFinishOrder);

        if (null != dispatchNetwork) {
            ZjWorkDispatchNetwork updateDispatchNetwork = new ZjWorkDispatchNetwork();
            updateDispatchNetwork.setId(dispatchNetwork.getId());
            updateDispatchNetwork.setStatus(checkStatementVo.getCheckType() == 1? WorkConstant.DISPATCH_NETWORK_STATUS_6 : WorkConstant.DISPATCH_NETWORK_STATUS_4);
            workDispatchNetworkService.updateById(updateDispatchNetwork);
        }
        if (null != dispatchEngineer) {
            ZjWorkDispatchEngineer updateEngineer = new ZjWorkDispatchEngineer();
            updateEngineer.setId(dispatchEngineer.getId());
            updateEngineer.setStatus(checkStatementVo.getCheckType() == 1? WorkConstant.DISPATCH_ENGINEER_STATUS_4 : WorkConstant.DISPATCH_ENGINEER_STATUS_2);
            updateEngineer.setNetworkEmpFinishTime(checkStatementVo.getCheckType() == 1? ZbDateConvertUtil.dateToDateStr(new Date()) : null);
            workDispatchEngineerService.updateById(updateEngineer);
        }

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(workId);
        updateOrder.setWaitCopeEvent(order.getWaitCopeEvent() -1);
        updateOrder.setUpdateEmpId(loginInfo.getId());
        updateOrder.setUpdateEmp(loginInfo.getName());
        updateOrder.setStatus(WorkConstant.WORK_STATUS_3);
        if (checkStatementVo.getCheckType() == 1) {
            updateOrder.setStatus(WorkConstant.WORK_STATUS_4);
            updateOrder.setEndTime(new Date());
            updateOrder.setEndOrder(true);
            updateOrder.setWaitCopeEvent(0);
            updateOrder.setNewAdvance(0);
            updateOrder.setSettlementStatus(WorkConstant.WORK_SETTLEMENT_STATUS_1);
        }
        workOrderService.updateById(updateOrder);

        ZjWorkDetail detail = new ZjWorkDetail();
        detail.setId(workId);
        detail.setEndOrderApply(false);
        workDetailService.updateById(detail);
        if (checkStatementVo.getCheckType() == 1) {
            workTotalFeeFreezeService.saveUnfreeze(loginInfo.getCustAccId(), order.getFactoryId(), order.getId());
            factoryOrderDeductionBillService.save(loginInfo.getCustAccId(), order.getFactoryId(), order.getId(), order.getCode(), order.getAllInclusiveFee(), order.getModulePrice());
            // 事务提交后执行
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    // 反写到乐开伙伴云
                    LKaiPushServiceImpl.pushOrderStatus(workId);
                }
            });
        }
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId, checkStatementVo.getCheckType() == 1? "审核结单，结单申请已审核通过" : "审核结单，结单申请已审核驳回", checkStatementVo.getRemark()));
        // 发送结单审核短信
        SendOrderFinishVo receiveVo = new SendOrderFinishVo(WorkUtilService.getOrderReceive(workId));
        receiveVo.setResult(checkStatementVo.getCheckType() == 1? "审核结果：已通过" : "审核结果：已驳回");
        receiveVo.setType(workModuleService.getById(order.getModuleId()).getName());
        SmsSendMessageService.sendOrderFinish(loginInfo, receiveVo);
    }
    // 根据工单ID驳回未结单工单
    @Override
    @Transactional
    public void backStatementOrder(AccounLoginInfo loginInfo, Long workId) {
        QueryWrapper<ZjWithdrawOrder> withdrawOrderQueryWrapper = new QueryWrapper<>();
        withdrawOrderQueryWrapper.select("id", "work_id", "work_no")
                .eq("work_id", workId);
        ZjWithdrawOrder zjWithdrawOrder = zjWithdrawOrderMapper.selectOne(withdrawOrderQueryWrapper);
        Assert.isTrue(zjWithdrawOrder == null,  "当前工单已审核提现结单！");

        //查询工单审核表记录
        QueryWrapper<ZjWorkFinishOrder> orderFinishQueryWrapper = new QueryWrapper<>();
        orderFinishQueryWrapper.select("id","status","work_id").eq("work_id",workId).eq("status",2);
        ZjWorkFinishOrder orderFinish = zjWorkFinishOrderMapper.selectOne(orderFinishQueryWrapper);
        Assert.isTrue(orderFinish != null,  "当前工单没有通过审核！");
        //查询登录账号是否为管理员
        QueryWrapper<ZjAccountRole> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("account_id","is_admin").eq("account_id",loginInfo.getId());
        ZjAccountRole accountAdminRole = zjAccountRoleMapper.getByCustAccIdAndAccountId(loginInfo.getCustAccId(), loginInfo.getId());
        Assert.isTrue(accountAdminRole != null,  "当前账号没有管理员权限");
        //查询工单详情
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.isTrue(order.getStatus() == WorkConstant.WORK_STATUS_4,  "当前工单没有完成");
        // 服务商
        ZjWorkDispatchNetwork dispatchNetwork = workDispatchNetworkService.getByWorkIdAndNetowrkId(workId, order.getNetworkId());
        Assert.isTrue(dispatchNetwork != null,  "查询不到分派网点信息");
        // 工程师
        ZjWorkDispatchEngineer dispatchEngineer = workDispatchEngineerService.getByWorkIdAndNetworkIdAndNetworkEmpId(workId, order.getNetworkId(), order.getNetworkEmpId());
        Assert.isTrue(dispatchEngineer != null,  "查询不到该工程师信息");

        if(accountAdminRole != null){
            //工单完成后，需要允许驳回重新提交结单（已审核结算单的不行）
            if(order.getStatus().equals(WorkConstant.WORK_STATUS_4) && order.getSettlementStatus().equals(WorkConstant.WORK_SETTLEMENT_STATUS_1)){
                if (null != dispatchNetwork) {
                    //服务商状态更新为待结单
                    dispatchNetwork.setId(dispatchNetwork.getId());
                    dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_5);
                    workDispatchNetworkService.updateById(dispatchNetwork);
                }
                //工程师状态更新为待结单
                if (null != dispatchEngineer) {
                    dispatchEngineer.setId(dispatchEngineer.getId());
                    dispatchEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_3);
                    workDispatchEngineerService.updateById(dispatchEngineer);
                }
                //设置该工单为未审核
                if(null != orderFinish){
                    orderFinish.setId(orderFinish.getId());
                    orderFinish.setStatus(WorkConstant.WORK_FINISH_ORDER_STATUS_1);
                    orderFinish.setRevieworEmpId(loginInfo.getId());
                    orderFinish.setRevieworEmp(loginInfo.getName());
                    orderFinish.setReviewTime(new Date());
                    workFinishOrderService.updateById(orderFinish);
                }
                //设置工单结单申请
                ZjWorkDetail workDetails = workDetailService.getById(workId);
                Assert.isFalse(workDetails == null,  "没有查询该工单结单申请信息");
                workDetails.setEndOrderApply(false);
                workDetailService.updateById(workDetails);
                //设置该工单为处理中
                order.setId(order.getId());
                order.setUpdateEmpId(loginInfo.getId());
                order.setUpdateEmp(loginInfo.getName());
                order.setStatus(WorkConstant.WORK_STATUS_3);
                order.setEndOrder(false);
                order.setSettlementStatus(WorkConstant.WORK_SETTLEMENT_STATUS_1);
                workOrderService.updateById(order);
                WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId,  "审核结单申请成功驳回" ));
                // 发送结单审核短信
                SendOrderFinishVo receiveVo = new SendOrderFinishVo(WorkUtilService.getOrderReceive(workId));
                receiveVo.setResult("审核结单申请成功驳回");
                receiveVo.setType(workModuleService.getById(order.getModuleId()).getName());
                SmsSendMessageService.sendOrderFinish(loginInfo, receiveVo);
            }
        }
    }


    // 根据工单ID获取待审核取消工单
    @Override
    public WorkCancelWaitCheckVo getWaitCheckCancelOrder(Long workId) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "取消工单参数[ " + workId + " ]的数据不存在");
        ZjWorkCancel workCancel = workCancelService.getWaitCheckCancelOrder(workId);
        Assert.notNull(workCancel, "当前取消待审核的工单");
        WorkCancelWaitCheckVo vo = new WorkCancelWaitCheckVo();
        BeanUtil.copyProperties(workCancel, vo);
        vo.setApplyTime(workCancel.getGmtCreate());
        vo.setNetwork(networkService.getNameById(order.getNetworkId()));
        return vo;
    }

    // 审核取消工单
    @Override
    @Transactional
    public void checkCancelOrder(AccounLoginInfo loginInfo, Long workId, WorkCheckCancelVo checkCancelVo) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "审核取消工单参数[ " + workId + " ]的数据不存在");
        Assert.isFalse(order.getStatus() == WorkConstant.WORK_STATUS_5, "当前工单已取消，禁止重复取消工单操作");
        ZjWorkCancel workCancel = workCancelService.getById(checkCancelVo.getId());
        Assert.notNull(workCancel, "当前工单没有待审核取消工单的数据");
        Assert.isTrue(workCancel.getStatus() == WorkConstant.WORK_CANCEL_STATUS_1, "当前取消工单已审核，禁止重复审核操作");

        ZjWorkCancel updateCancel = new ZjWorkCancel();
        updateCancel.setId(workCancel.getId());
        updateCancel.setStatus(checkCancelVo.getCheckType() == 1? WorkConstant.WORK_CANCEL_STATUS_2 : WorkConstant.WORK_CANCEL_STATUS_3);
        updateCancel.setReviewEmpId(loginInfo.getId());
        updateCancel.setReviewEmp(loginInfo.getName());
        updateCancel.setReviewTime(new Date());
        updateCancel.setReviewRemark(checkCancelVo.getRemark());
        workCancelService.updateById(updateCancel);

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(workId);
        updateOrder.setWaitCopeEvent(order.getWaitCopeEvent() -1);
        updateOrder.setUpdateEmpId(loginInfo.getId());
        updateOrder.setUpdateEmp(loginInfo.getName());

        ZjWorkDetail workDetail = new ZjWorkDetail();
        workDetail.setId(workId);
        workDetail.setCancelOrderApply(false);
        workDetailService.updateById(workDetail);
        // 驳回
        if (checkCancelVo.getCheckType() == 2) {
            workOrderService.updateById(updateOrder);
            WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId, "审核取消工单，审核结果：已驳回", checkCancelVo.getRemark()));
            return;
        }
        updateOrder.setStatus(WorkConstant.WORK_STATUS_5);
        updateOrder.setWaitCopeEvent(0);
        updateOrder.setNewAdvance(0);
        updateOrder.setCancelTime(new Date());
        workOrderService.updateById(updateOrder);
        // 释放占用金额
        workTotalFeeFreezeService.saveUnfreeze(loginInfo.getCustAccId(), order.getFactoryId(), order.getId());
        // 获取商家工单的所有费用
        BigDecimal factoryAllFee = workOrderService.getFactoryAllFeeById(order.getId());
        // 工单取消，解冻金额
        factoryAccountBalanceService.updateFreezePriceById(order.getFactoryId(), new BigDecimal("0.0").subtract(factoryAllFee));

        // 查询服务商
        ZjWorkDispatchNetwork dispatchNetwork = workDispatchNetworkService.getByWorkIdAndNetowrkId(workId, order.getNetworkId());
        if (null != dispatchNetwork) {
            ZjWorkDispatchNetwork updateNetwork = new ZjWorkDispatchNetwork();
            updateNetwork.setId(dispatchNetwork.getId());
            updateNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_7);
            workDispatchNetworkService.updateById(updateNetwork);
        }
        // 查询工程师
        ZjWorkDispatchEngineer dispatchEngineer = workDispatchEngineerService.getByNetworkEmpIdAndWorkId(order.getNetworkEmpId(), order.getId());
        if (null != dispatchEngineer) {
            ZjWorkDispatchEngineer updateEngineer = new ZjWorkDispatchEngineer();
            updateEngineer.setId(dispatchEngineer.getId());
            updateEngineer.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_5);
            workDispatchEngineerService.updateById(updateEngineer);
        }
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId, "审核取消工单，审核结果：已通过", checkCancelVo.getRemark()));
        // 发送取消工单短信
        SmsSendMessageService.sendOrderCancel(loginInfo, new SendOrderCancelVo(WorkUtilService.getOrderReceive(workId), "已取消"));
    }

    // 获取待审核的工单事件
    @Override
    public List<WorkWaitCheckOrderEvent> getWaitCheckOrderEvent(Long workId) {
        return workOrderService.getWaitCheckOrderEventByWorkId(workId);
    }

    // 保存工单催单
    @Override
    @Transactional
    public void saveReminder(AccounLoginInfo loginInfo, OrderReminderVo reminderVo) throws ZbException {
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("id", "code", "status", "reminder_num", "emp_id", "network_id", "network_emp_id")
                .in("id", reminderVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(orderQueryWrapper);
        List<String> codes = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4 || f.getStatus() == WorkConstant.WORK_STATUS_5).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(codes), "当前工单流程已完成或已取消，禁止重复操作工单：" + String.join("、", codes));
        // 工单客服
        List<ZjAccount> accountList = new ArrayList<>();
        // 服务商负责人
        List<ViewNetworkEmpDetail> networkEmpDetails = new ArrayList<>();
        // 工程师
        List<ViewNetworkEmpAccount> networkEmpAccountList = new ArrayList<>();
        workSlaUtilService.getReminderEmpInfo(accountList, networkEmpDetails, networkEmpAccountList, reminderVo.getRemindEmpType(), null, orderList);

        List<ZjWorkReminder> reminderList = new ArrayList<>();
        ZjWorkReminder reminder = null;
        List<WorkLogVo> voList = new ArrayList<>();
        List<ZjWorkOrder> updateOrderList = new ArrayList<>();
        ZjWorkOrder updateOrder = null;
        List<SendWorkRemindVo> workRemindVoList = new ArrayList<>();
        ZjWorkOrder workOrder = null;
        ReceiveVo receiveEmp = null;
        for (Long workId : reminderVo.getWorkIds()) {
            reminder = new ZjWorkReminder();
            reminder.setId(IdWorker.getId());
            reminder.setCustAccId(loginInfo.getCustAccId());
            reminder.setWorkId(workId);
            reminder.setEmpType(WorkConstant.REMINDER_EMP_TYPE_1);
            reminder.setEmp(loginInfo.getName());
            reminder.setContent(reminderVo.getContent());
            reminderList.add(reminder);

            workOrder = orderList.stream().filter(f -> Objects.equals(f.getId(), workId)).findFirst().orElse(null);

            updateOrder = new ZjWorkOrder();
            updateOrder.setId(workId);
            updateOrder.setReminderNum(null != workOrder? workOrder.getReminderNum() +1 : 0);
            updateOrderList.add(updateOrder);
            voList.add(new WorkLogVo(loginInfo, workId, "工单催单", reminderVo.getContent()));

            if (CollectionUtil.isNotEmpty(reminderVo.getRemindEmpType())) {
                for (Integer remindEmpType : reminderVo.getRemindEmpType()) {
                    receiveEmp = workSlaUtilService.getReceiveEmpInfo(remindEmpType, accountList, networkEmpDetails, networkEmpAccountList, workOrder);
                    if (null != receiveEmp) {
                        workRemindVoList.add(new SendWorkRemindVo(receiveEmp, null != workOrder? workOrder.getCode() : ""));
                    }
                }
            }
        }
        workReminderService.saveBatch(reminderList);
        workOrderService.updateBatchById(updateOrderList);
        SmsSendMessageService.sendWorkRemind(loginInfo, workRemindVoList);
        WorkServiceLog.saveService(voList);
    }

    // 工单超时提醒
    @Override
    public WorkTimeoutRemindResultVo workTimeoutRemind(AccounLoginInfo loginInfo, WorkTimeoutRemindVo workTimeoutRemindVo) throws ZbException {
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("id", "module_id", "code", "status", "reminder_num", "is_assign_emp AS assignEmp", "emp_id", "network_id", "network_emp_id", "gmt_create", "gmt_update")
                .in("id", workTimeoutRemindVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(orderQueryWrapper);
        List<String> codes = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4 || f.getStatus() == WorkConstant.WORK_STATUS_5).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(codes), "工单流程已完成或已取消，不允许发送提醒！工单号：" + String.join("、", codes));
        List<ZjWorkModule> moduleList = workModuleService.getPartInfoByIds(orderList.stream().map(ZjWorkOrder::getModuleId).distinct().toList());
        // 工单客服
        List<ZjAccount> accountList = new ArrayList<>();
        // 服务商负责人
        List<ViewNetworkEmpDetail> networkEmpDetails = new ArrayList<>();
        // 工程师
        List<ViewNetworkEmpAccount> networkEmpAccountList = new ArrayList<>();
        List<WorkLogVo> logVos = new ArrayList<>();
        List<SendWorkTimeoutRemindVo> workTimeoutRemindVos = new ArrayList<>();
        SendWorkTimeoutRemindVo remindVo = null;
        String moduleName = null;
        Set<String> conditionTypeSet = new HashSet<>();
        List<String> errorMessage = new ArrayList<>();
        StringBuilder remindRemarkBuilder = new StringBuilder();
        // 手动触发提醒
        if (workTimeoutRemindVo.getType() == 1) {
            workSlaUtilService.getReminderEmpInfo(accountList, networkEmpDetails, networkEmpAccountList, workTimeoutRemindVo.getRemindEmpType(), workTimeoutRemindVo.getRemindEmpIds(), orderList);
            ReceiveVo receiveEmp = null;
            for (ZjWorkOrder order : orderList) {
                conditionTypeSet.add(WorkConverter.reminderNodeConditionConverter(workTimeoutRemindVo.getConditionType()));
                if (!order.getAssignEmp() && workTimeoutRemindVo.getRemindEmpType().stream().anyMatch(f -> f == 1)) {
                    remindRemarkBuilder.append("工单没有分配客服，无法提醒客服；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(workTimeoutRemindVo.getConditionType()) + "；工单没有分配客服，无法提醒客服"));
                }
                if (order.getNetworkId() == 0 && workTimeoutRemindVo.getRemindEmpType().stream().anyMatch(f -> f == 2)) {
                    remindRemarkBuilder.append("工单没有派单，无法提醒服务商负责人；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(workTimeoutRemindVo.getConditionType()) + "；工单没有派单，无法提醒服务商负责人"));
                }
                if (order.getNetworkEmpId() == 0 && workTimeoutRemindVo.getRemindEmpType().stream().anyMatch(f -> f == 3)) {
                    remindRemarkBuilder.append("工单没有派工，无法提醒工程师；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(workTimeoutRemindVo.getConditionType()) + "；工单没有派工，无法提醒工程师"));
                }
                if (remindRemarkBuilder.length() > 0) {
                    errorMessage.add("工单号：" + order.getCode() + "：" + remindRemarkBuilder.delete(remindRemarkBuilder.length()-1, remindRemarkBuilder.length()));
                    remindRemarkBuilder.delete(0, remindRemarkBuilder.length());
                }
                moduleName = moduleList.stream().filter(f -> Objects.equals(f.getId(), order.getModuleId())).findFirst().map(ZjWorkModule::getName).orElse("");
                for (Integer remindEmpType : workTimeoutRemindVo.getRemindEmpType()) {
                    receiveEmp = workSlaUtilService.getReceiveEmpInfo(remindEmpType, accountList, networkEmpDetails, networkEmpAccountList, order);
                    if (null != receiveEmp) {
                        remindVo = new SendWorkTimeoutRemindVo(receiveEmp, order.getCode());
                        remindVo.setReminderNode(WorkConverter.reminderNodeConditionConverter(workTimeoutRemindVo.getConditionType()));
                        remindVo.setState(WorkConverter.workStatusConverter(order.getStatus()));
                        remindVo.setType(moduleName);
                        workTimeoutRemindVos.add(remindVo);
                    }
                }
            }
            SmsSendMessageService.sendManualTriggerWorkTimeoutRemind(loginInfo, workTimeoutRemindVos);
            WorkServiceLog.saveService(logVos);
            return CollectionUtil.isEmpty(errorMessage)? null : new WorkTimeoutRemindResultVo(
                    String.join("、", conditionTypeSet),
                    workTimeoutRemindVo.getRemindEmpType().stream().map(t -> {
                        return t == 1? "工单客服" : t == 2? "服务商负责人" : t == 3? "工程师" : "指定人员";
                    }).collect(Collectors.joining("、")),
                    errorMessage
            );
        }
        // 根据SLA规则触发提醒
        // 获取提醒人员
        List<WorkSlaConditionExtend> slaConditionExtends = workSlaConditionService.getByModuleIds(moduleList.stream().map(ZjWorkModule::getId).toList());
        List<Long> networkIds = new ArrayList<>();
        List<Long> networkEmpIds = new ArrayList<>();
        List<Long> empIds = new ArrayList<>();
        for (ZjWorkOrder order : orderList) {
            if (order.getAssignEmp() && slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("1"))) {
                empIds.add(order.getEmpId());
            }
            if (order.getNetworkId() > 0 && slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("3"))) {
                networkIds.add(order.getNetworkId());
            }
            if (order.getNetworkEmpId() > 0 && slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("4"))) {
                networkEmpIds.add(order.getNetworkId());
            }
        }
        accountList.addAll(accountService.getByIds(empIds));
        networkEmpDetails.addAll(viewNetworkEmpDetailService.getManagerByNetworkIds(networkIds));
        networkEmpAccountList.addAll(viewNetworkEmpAccountService.getByIds(networkEmpIds));
        // 获取工单节点超时信息
        List<OrderSlaVo> orderSlaVoList = workSlaUtilService.getOrderSlaInfo(orderList.stream().map(order -> {
            return new OrderSlaSelectVo(order.getId(), order.getModuleId(), order.getStatus(), order.getAssignEmp(), order.getGmtCreate(), order.getGmtUpdate());
        }).toList());
        Set<String> remindEmpSet = new HashSet<>();
        OrderSlaVo orderSlaVo = null;
        ZjAccount account = null;
        ViewNetworkEmpDetail viewNetworkEmpDetail = null;
        ViewNetworkEmpAccount networkEmpAccount = null;
        List<WorkSlaConditionRemindEmpExtend> workSlaConditionRemindEmpList = new ArrayList<>();
        for (ZjWorkOrder order : orderList) {
            orderSlaVo = orderSlaVoList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().orElse(null);
            if (null == orderSlaVo) {
                continue;
            }
            conditionTypeSet.add(WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()));
            workSlaConditionRemindEmpList.clear();
            moduleName = moduleList.stream().filter(f -> Objects.equals(f.getId(), order.getModuleId())).findFirst().map(ZjWorkModule::getName).orElse("");
            networkEmpAccount = networkEmpAccountList.stream().filter(f -> Objects.equals(f.getId(), order.getNetworkEmpId())).findFirst().orElse(null);
            // 工单客服
            if (slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("1"))) {
                account = accountList.stream().filter(f -> Objects.equals(f.getId(), order.getEmpId())).findFirst().orElse(null);
                if (order.getAssignEmp() && null != account) {
                    workTimeoutRemindVos.add(new SendWorkTimeoutRemindVo(account.getPhone(), account.getName(), order.getCode(), moduleName,
                            WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()), orderSlaVo.getNodeTimeoutLength(),
                            null != networkEmpAccount ? networkEmpAccount.getName() : "暂无"
                    ));
                } else {
                    remindEmpSet.add("工单客服");
                    remindRemarkBuilder.append("工单没有分配客服，无法提醒客服；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()) + "；工单没有分配客服，无法提醒客服"));
                }
            }
            // 指定人员
            if (slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("2"))) {
                remindEmpSet.add("指定人员");
                slaConditionExtends.stream().filter(f -> Objects.equals(f.getModuleId(), order.getModuleId())).map(WorkSlaConditionExtend::getWorkSlaConditionRemindEmpList).forEach(t -> {
                    workSlaConditionRemindEmpList.addAll(t);
                });
                for (WorkSlaConditionRemindEmpExtend emp : workSlaConditionRemindEmpList) {
                    workTimeoutRemindVos.add(new SendWorkTimeoutRemindVo(
                            emp.getPhone(), emp.getEmp(), order.getCode(), moduleName,
                            WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()), orderSlaVo.getNodeTimeoutLength(),
                            null != networkEmpAccount? networkEmpAccount.getName() : "暂无"
                    ));
                }
            }
            // 服务商负责人
            if (slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("3"))) {
                viewNetworkEmpDetail = networkEmpDetails.stream().filter(f -> Objects.equals(f.getNetworkId(), order.getNetworkEmpId())).findFirst().orElse(null);
                if (order.getNetworkId() > 0 && null != viewNetworkEmpDetail) {
                    workTimeoutRemindVos.add(new SendWorkTimeoutRemindVo(viewNetworkEmpDetail.getAccountPhone(), viewNetworkEmpDetail.getAccountName(), order.getCode(), moduleName,
                            WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()), orderSlaVo.getNodeTimeoutLength(),
                            null != networkEmpAccount? networkEmpAccount.getName() : "暂无"
                    ));
                } else {
                    remindEmpSet.add("服务商负责人");
                    remindRemarkBuilder.append("工单没有派单，无法提醒服务商负责人；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()) + "；工单没有派单，无法提醒服务商负责人"));
                }
            }
            // 工程师
            if (slaConditionExtends.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("4"))) {
                if (order.getNetworkEmpId() > 0 && null != networkEmpAccount) {
                    workTimeoutRemindVos.add(new SendWorkTimeoutRemindVo(networkEmpAccount.getPhone(), networkEmpAccount.getName(),order.getCode(), moduleName,
                            WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()), orderSlaVo.getNodeTimeoutLength(), networkEmpAccount.getName()
                    ));
                } else {
                    remindEmpSet.add("工程师");
                    remindRemarkBuilder.append("工单没有派工，无法提醒工程师；");
                    logVos.add(new WorkLogVo(loginInfo, order.getId(), "工单超时未处理提醒", "提醒状态节点："+ WorkConverter.reminderNodeConditionConverter(orderSlaVo.getType()) + "；工单没有派工，无法提醒工程师"));
                }
            }
            if (remindRemarkBuilder.length() > 0) {
                errorMessage.add("工单号：" + order.getCode() + "：" + remindRemarkBuilder.delete(remindRemarkBuilder.length()-1, remindRemarkBuilder.length()));
                remindRemarkBuilder.delete(0, remindRemarkBuilder.length());
            }
        }
        SmsSendMessageService.sendWorkTimeoutRemind(loginInfo, workTimeoutRemindVos);
        WorkServiceLog.saveService(logVos);
        return CollectionUtil.isEmpty(errorMessage)? null : new WorkTimeoutRemindResultVo(
                String.join("、", conditionTypeSet),
                String.join("、", remindEmpSet),
                errorMessage
        );
    }

    // 批量更新工单流程为完成
    @Override
    @Transactional
    public void finishOrder(AccounLoginInfo loginInfo, OrderEventVo orderEventVo) {
        Assert.isTrue(CollectionUtil.isNotEmpty(orderEventVo.getWorkIds()), "必须指定要完成工单流程的工单");
        QueryWrapper<ZjWorkOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id", "code", "status");
        wrapper.in("id", orderEventVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(wrapper);
        List<String> workNos = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(workNos), "当前的工单流程已完成，不允许更改！工单号："+ String.join("、", workNos));
        workNos = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_5).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(workNos), "当前的工单流程已取消，不允许更改！工单号："+ String.join("、", workNos));

        QueryWrapper<ZjWorkDetail> workDetailQueryWrapper = new QueryWrapper<>();
        workDetailQueryWrapper.select("id", "no_review_apply_work_fee_num", "no_review_apply_work_spare_num", "is_end_order_apply AS endOrderApply",
                        "is_cancel_order_apply AS cancelOrderApply", "is_change_network_apply AS changeNetworkApply")
                .in("id", orderEventVo.getWorkIds());
        List<ZjWorkDetail> detailList = workDetailService.list(workDetailQueryWrapper);
        List<Long> workIds = new ArrayList<>();
        workIds.addAll(detailList.stream().filter(f -> f.getNoReviewApplyWorkFeeNum() > 0).map(ZjWorkDetail::getId).toList());
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单存在未审核的费用项，不允许完成工单！工单号：" + orderList.stream()
                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
        workIds.clear();
        workIds.addAll(detailList.stream().filter(f -> f.getNoReviewApplyWorkSpareNum() > 0).map(ZjWorkDetail::getId).toList());
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单存在未审核的工单配件项，不允许完成工单！工单号：" + orderList.stream()
                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
        workIds.clear();
        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getEndOrderApply).map(ZjWorkDetail::getId).toList());
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请结单待审核项，不允许完成工单！工单号：" + orderList.stream()
                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
        workIds.clear();
        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getCancelOrderApply).map(ZjWorkDetail::getId).toList());
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请取消工单待审核项，不允许完成工单！工单号：" + orderList.stream()
                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
        workIds.clear();
        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getChangeNetworkApply).map(ZjWorkDetail::getId).toList());
        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请改派工单待审核项，不允许完成工单！工单号：" + orderList.stream()
                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));

        QueryWrapper<ZjWorkDispatchNetwork> dispatchNetworkQueryWrapper = new QueryWrapper<>();
        dispatchNetworkQueryWrapper.select("id", "status")
                .in("work_id", orderEventVo.getWorkIds())
                .between("status", WorkConstant.DISPATCH_NETWORK_STATUS_1, WorkConstant.DISPATCH_NETWORK_STATUS_4);
        List<ZjWorkDispatchNetwork> dispatchNetworkList = workDispatchNetworkService.list(dispatchNetworkQueryWrapper);
        dispatchNetworkList.forEach(t -> {
            t.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_6);
        });
        // 查询工程师
        QueryWrapper<ZjWorkDispatchEngineer> dispatchEngineerQueryWrapper = new QueryWrapper<>();
        dispatchEngineerQueryWrapper.select("id",  "status")
                .in("work_id", orderEventVo.getWorkIds())
                .between("status", WorkConstant.DISPATCH_ENGINEER_STATUS_1, WorkConstant.DISPATCH_ENGINEER_STATUS_2);
        List<ZjWorkDispatchEngineer> dispatchEngineerList = workDispatchEngineerService.list(dispatchEngineerQueryWrapper);
        dispatchEngineerList.forEach(t -> {
            t.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_4);
        });
        // 获取提现冻结天数
        Integer withdrawFreezeDay = withdrawSetService.getWithdrawFreezeDayByCustAccId(loginInfo.getCustAccId());
        List<ZjWorkOrder> updateOrders = new ArrayList<>();
        List<WorkLogVo> logVos = new ArrayList<>();
        ZjWorkOrder order = null;
        for (Long id : orderEventVo.getWorkIds()) {
            order = new ZjWorkOrder();
            order.setId(id);
            order.setStatus(WorkConstant.WORK_STATUS_4);
            order.setSettlementStatus(WorkConstant.WORK_SETTLEMENT_STATUS_1);
            order.setWithdrawFreezeDay(withdrawFreezeDay);
            order.setEndOrder(true);
            order.setEndTime(new Date());
            order.setNewAdvance(0);
            order.setWaitCopeEvent(0);
            order.setUpdateEmpId(loginInfo.getId());
            order.setUpdateEmp(loginInfo.getName());
            updateOrders.add(order);
            logVos.add(new WorkLogVo(loginInfo, id, "更改工单流程为已完成", orderEventVo.getRemark()));
        }
        workOrderService.updateBatchById(updateOrders);
        workTotalFeeFreezeService.saveUnfreeze(loginInfo.getCustAccId(), orderList);
        conFactoryAccountBalanceService.deductionFreezeByWorkIds(true, orderEventVo.getWorkIds());
        if (CollectionUtil.isNotEmpty(dispatchNetworkList)) workDispatchNetworkService.updateBatchById(dispatchNetworkList);
        if (CollectionUtil.isNotEmpty(dispatchEngineerList)) workDispatchEngineerService.updateBatchById(dispatchEngineerList);
        WorkServiceLog.saveService(logVos);
    }

    // 批量更新工单流程为取消
    @Override
    @Transactional
    public void cancelOrder(AccounLoginInfo loginInfo, OrderEventVo orderEventVo) {
        Assert.isTrue(CollectionUtil.isNotEmpty(orderEventVo.getWorkIds()), "必须指定要取消工单流程的工单");
        QueryWrapper<ZjWorkOrder> wrapper = new QueryWrapper<>();
        wrapper.select("id", "module_id", "code", "status")
                .in("id", orderEventVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(wrapper);
//        List<String> workNos = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_5).map(ZjWorkOrder::getCode).toList();
//        Assert.isTrue(CollectionUtil.isEmpty(workNos), "当前的工单流程已取消，不允许更改！工单号："+ String.join("、", workNos));
//        workNos = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4).map(ZjWorkOrder::getCode).toList();
//        Assert.isTrue(CollectionUtil.isEmpty(workNos), "当前的工单流程已完成，不允许更改！工单号："+ String.join("、", workNos));

        QueryWrapper<ZjWorkDetail> workDetailQueryWrapper = new QueryWrapper<>();
        workDetailQueryWrapper.select("id", "no_review_apply_work_fee_num", "no_review_apply_work_spare_num", "is_end_order_apply AS endOrderApply",
                        "is_cancel_order_apply AS cancelOrderApply", "is_change_network_apply AS changeNetworkApply")
                .in("id", orderEventVo.getWorkIds());
//        List<ZjWorkDetail> detailList = workDetailService.list(workDetailQueryWrapper);
//        List<Long> workIds = new ArrayList<>();
//        workIds.addAll(detailList.stream().filter(f -> f.getNoReviewApplyWorkFeeNum() > 0).map(ZjWorkDetail::getId).toList());
//        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单存在未审核的费用项，不允许取消！工单号：" + orderList.stream()
//                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
//        workIds.clear();
//        workIds.addAll(detailList.stream().filter(f -> f.getNoReviewApplyWorkSpareNum() > 0).map(ZjWorkDetail::getId).toList());
//        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单存在未审核的工单配件项，不允许取消！工单号：" + orderList.stream()
//                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
//        workIds.clear();
//        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getEndOrderApply).map(ZjWorkDetail::getId).toList());
//        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请结单待审核，不允许取消！工单号：" + orderList.stream()
//                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
//        workIds.clear();
//        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getCancelOrderApply).map(ZjWorkDetail::getId).toList());
//        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请取消工单待审核，不允许取消！工单号：" + orderList.stream()
//                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));
//        workIds.clear();
//        workIds.addAll(detailList.stream().filter(ZjWorkDetail::getChangeNetworkApply).map(ZjWorkDetail::getId).toList());
//        Assert.isTrue(CollectionUtil.isEmpty(workIds), "工单已申请改派工单待审核，不允许取消！工单号：" + orderList.stream()
//                .filter(f -> workIds.stream().anyMatch(f1 -> Objects.equals(f1, f.getId()))).map(ZjWorkOrder::getCode).collect(Collectors.joining("、")));

        QueryWrapper<ZjWorkDispatchNetwork> dispatchNetworkQueryWrapper = new QueryWrapper<>();
        dispatchNetworkQueryWrapper.select("id", "status")
                .in("work_id", orderEventVo.getWorkIds())
                .between("status", WorkConstant.DISPATCH_NETWORK_STATUS_1, WorkConstant.DISPATCH_NETWORK_STATUS_4);
        List<ZjWorkDispatchNetwork> dispatchNetworkList = workDispatchNetworkService.list(dispatchNetworkQueryWrapper);
        dispatchNetworkList.forEach(t -> {
            t.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_7);
        });
        // 查询工程师
        QueryWrapper<ZjWorkDispatchEngineer> dispatchEngineerQueryWrapper = new QueryWrapper<>();
        dispatchEngineerQueryWrapper.select("id",  "status")
                .in("work_id", orderEventVo.getWorkIds())
                .between("status", WorkConstant.DISPATCH_ENGINEER_STATUS_1, WorkConstant.DISPATCH_ENGINEER_STATUS_2);
        List<ZjWorkDispatchEngineer> dispatchEngineerList = workDispatchEngineerService.list(dispatchEngineerQueryWrapper);
        dispatchEngineerList.forEach(t -> {
            t.setStatus(WorkConstant.DISPATCH_ENGINEER_STATUS_5);
        });
        // 获取提现冻结天数
        Integer withdrawFreezeDay = withdrawSetService.getWithdrawFreezeDayByCustAccId(loginInfo.getCustAccId());
        List<ZjWorkOrder> updateOrders = new ArrayList<>();
        List<WorkLogVo> logVos = new ArrayList<>();
        ZjWorkOrder order = null;
        ArrayList<Long> idList = new ArrayList<>();
        for (Long id : orderEventVo.getWorkIds()) {
            order = new ZjWorkOrder();
            order.setId(id);
            order.setStatus(WorkConstant.WORK_STATUS_5);
            order.setWithdrawFreezeDay(withdrawFreezeDay);
            order.setCancelTime(new Date());
            order.setNewAdvance(0);
            order.setWaitCopeEvent(0);
            order.setUpdateEmpId(loginInfo.getId());
            order.setUpdateEmp(loginInfo.getName());
            order.setNewAdvance(0);
            order.setCancelReason(orderEventVo.getCancelReason());
            updateOrders.add(order);
            logVos.add(new WorkLogVo(loginInfo, id, "取消工单", "取消原因：" + orderEventVo.getRemark()));
            idList.add(id);
        }
        workOrderService.updateBatchById(updateOrders);
        workTotalFeeFreezeService.saveUnfreeze(loginInfo.getCustAccId(), orderList);
        conFactoryAccountBalanceService.deductionFreezeByWorkIds(false, orderEventVo.getWorkIds());
        if (CollectionUtil.isNotEmpty(dispatchNetworkList)) workDispatchNetworkService.updateBatchById(dispatchNetworkList);
        if (CollectionUtil.isNotEmpty(dispatchEngineerList)) workDispatchEngineerService.updateBatchById(dispatchEngineerList);
        WorkServiceLog.saveService(logVos);

        // 发送通知短信
        List<OrderReceiveVo> orderReceive = WorkUtilService.getOrderReceive(orderEventVo.getWorkIds());
        SmsSendMessageService.sendOrderCancel(loginInfo, orderReceive.stream().map(receiveVo -> {
            return new SendOrderCancelVo(receiveVo, "已取消");
        }).toList());
        // 本地取消
        if (orderEventVo.getApproach().equals(5)) {
            return;
        }
        //取消工单触发
        for (Long id : idList) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    // 反写到乐开伙伴云
                    LKaiPushServiceImpl.pushOrderStatus(id);
                }
            });
        }
    }

    @Override
    public void workAgain(ZjWorkOrder zjWorkOrder) {
        ZjWorkOrder order = new ZjWorkOrder();
        order.setId(zjWorkOrder.getId());
        order.setIsWorkAgain(zjWorkOrder.getIsWorkAgain());
        order.setWorkAgainMsg(zjWorkOrder.getWorkAgainMsg());
        zjWorkOrderMapper.updateById(order);
    }

    @Override
    public void signImage(ZjWorkOrder zjWorkOrder) {
        zjWorkOrderMapper.updateById(zjWorkOrder);
    }

    // 更改结算价
    @Override
    @Transactional
    public void updateSettlementPrice(AccounLoginInfo loginInfo, WorkSettlementPriceVo workSettlementPriceVo) {
        if (CollectionUtil.isEmpty(workSettlementPriceVo.getWorkIds())) {
            return;
        }
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("id", "status", "module_price", "network_module_price", "factory_settlement_deduction_price", "network_settlement_deduction_price")
                .in("id", workSettlementPriceVo.getWorkIds());
        List<ZjWorkOrder> orderList = workOrderService.list(orderQueryWrapper);
        List<String> codes = orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4 || f.getStatus() == WorkConstant.WORK_STATUS_5).map(ZjWorkOrder::getCode).toList();
        Assert.isTrue(CollectionUtil.isEmpty(codes), "更改结算价的工单流程已完成或已取消，禁止更改结算价，禁止更改的工单单号：" + String.join("、", codes));
        // 查询工单配件、服务费用结算价
        List<OrderSettlementPriceVo> settlementPriceVoList = workOrderService.getOrderSettlementPriceByWorkId(orderList.stream().map(ZjWorkOrder::getId).toList());

        List<ZjWorkOrder> updateOrderList = new ArrayList<>();
        ZjWorkOrder updateOrder = null;
        List<WorkLogVo> logVos = new ArrayList<>();
        OrderSettlementPriceVo settlementPriceVo = null;
        for (ZjWorkOrder order : orderList) {
            updateOrder = new ZjWorkOrder();
            updateOrder.setId(order.getId());
            settlementPriceVo = settlementPriceVoList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().orElse(null);
            if (null != settlementPriceVo) {
                // 计算存在的扣减价格
                updateOrder.setFactorySettlementDeductionPrice(
                        // 工单原总价格合计：模块费用 + 收取商家的（配件、服务费）费用合计
                        order.getModulePrice().add(settlementPriceVo.getReceiveFactoryPrice())
                                // 减去传入的合计结算价
                                .subtract(workSettlementPriceVo.getFactorySettlementPrice())
                );
                updateOrder.setNetworkSettlementDeductionPrice(
                        // 工单原总价格合计：网点模块费用 + 支付网点的（配件、服务费）费用合计
                        order.getNetworkModulePrice().add(settlementPriceVo.getPayNetworkPrice())
                                // 减去传入的合计结算价
                                .subtract(workSettlementPriceVo.getNetworkSettlementPrice())
                );
            } else {
                // 计算存在的扣减价格
                updateOrder.setFactorySettlementDeductionPrice(
                        order.getModulePrice()
                                // 减去传入的合计结算价
                                .subtract(workSettlementPriceVo.getFactorySettlementPrice())
                );
                updateOrder.setNetworkSettlementDeductionPrice(
                        // 工单原总价格合计：网点模块费用
                        order.getNetworkModulePrice()
                                // 减去传入的合计结算价
                                .subtract(workSettlementPriceVo.getNetworkSettlementPrice())
                );
            }
            updateOrderList.add(updateOrder);
            logVos.add(new WorkLogVo(loginInfo, order.getId(), "更新工单结算价"));
        }
        workOrderService.updateBatchById(updateOrderList);
        WorkServiceLog.saveService(logVos);
    }

    // 根据工单ID获取结单字段
    @Override
    public List<WorkFinishOrderTemplateVo> getOrderSettlementField(Long workId) {
        ZjWorkOrder order = workOrderService.getById(workId);
        if (null == order) {
            return new ArrayList<>();
        }
        ZjWorkFinishOrder workFinishOrder = workFinishOrderService.getEndOrderByWorkIdAndNetworkId(workId, order.getNetworkId());
        if (null == workFinishOrder) {
            return new ArrayList<>();
        }
        List<WorkFinishOrderTemplateExtend> orderTemplates = workFinishOrderTemplateService.getByWorkFinishOrderId(workFinishOrder.getId());
        List<WorkFinishOrderTemplateFieldValExtend> extendList = workFinishOrderTemplateFieldValService.getByWorkStatementTemplateIds(orderTemplates.stream().map(WorkFinishOrderTemplateExtend::getId).toList());
        return orderTemplates.stream().map(template -> {
            WorkFinishOrderTemplateVo templateVo = new WorkFinishOrderTemplateVo();
            templateVo.setTemplate(template.getTemplate());
            templateVo.setFieldVals(extendList.stream().filter(f -> Objects.equals(f.getWorkFinishOrderTemplateId(), template.getId())).map(fieldVal -> {
                FieldValVo valVo = new FieldValVo();
                valVo.setId(fieldVal.getId());
                valVo.setType(fieldVal.getType());
                valVo.setName(fieldVal.getName());
                valVo.setOptVos(fieldVal.getVals());
                return valVo;
            }).toList());
            return templateVo;
        }).toList();
    }
    //根据工单ID打印
    @Override
    public WorkOrderDetailsPrintedVo getWorkOrderDetailsPrinted(Long id) {
        ZjWorkOrder order = workOrderService.getById(id);
        Assert.isTrue(null != order, "系统中没有此工单");
        WorkOrderDetailsPrintedVo vo = new WorkOrderDetailsPrintedVo();
        BeanUtil.copyProperties(order, vo);
        //工单单号
        vo.setOrderNo(order.getCode());
        //申请时间
        vo.setCreateTime(order.getGmtCreate());
        ZjWorkLevel workLevel = workLevelService.getById(order.getWorkLevelId());
        if (null != workLevel) {
            //工单级别
            vo.setWorkLevel(workLevel.getName());
        }
        CodeVo codeVo = new CodeVo();
        BeanUtils.copyProperties(vo, codeVo);
        //工单质保天数
        vo.setWarrantyDay(order.getWarrantyDay());
        ZjWorkUser workUser = workUserService.getById(id);
        ZjUser user = userService.getById(workUser.getUserId());
        //客户名称
        vo.setUserName(user.getName());
        //客户电话
        vo.setContactsPhone(workUser.getPhone());
        //客户地址
        vo.setProvince(workUser.getProvince());
        vo.setCity(workUser.getCity());
        vo.setArea(workUser.getArea());
        vo.setTown(workUser.getTown());
        //客户地址-详情地址
        vo.setAddress(workUser.getAddress());
        //工单图片
        vo.setOrderImages(workImageService.getByWorkId(id).stream().map(ZjWorkImage::getImage).toList());
        ZjWorkDetail workDetail = workDetailService.getById(id);
        //工单内容
        vo.setContent(workDetail.getContent());
        vo.setOverinsured(workOrderService.QualityAccId(id));
        //受理网点
        vo.setName(networkService.getNameById(order.getNetworkId()));
        //网点人员
        ViewNetworkEmpDetail networkEmpDetail = viewNetworkEmpDetailService.getManagerByNetworkId(order.getNetworkId());
        vo.setNetworkManaterEmp(networkEmpDetail.getAccountName());
        //工程师
        ViewNetworkEmpDetail empDetail = viewNetworkEmpDetailService.getByNetworkIdAndNetworkEmpId(order.getNetworkId(), order.getNetworkEmpId());
        vo.setEngineer(empDetail.getAccountName());
        //受理客服
        ZjAccount account = accountService.getById(order.getEmpId());
        if (null != account) {
            vo.setEmp(account.getName());
        }
        Date createTimeDate = order.getGmtCreate();  // 工单创建时间
        Date endTimeDate = (order.getEndTime() != null) ? order.getEndTime() : new Date();  // 工单完成时间，如果为空则使用当前时间

        // 将 Date 转换为 LocalDateTime
        LocalDateTime createTime = createTimeDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime endTime = endTimeDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

        // 计算服务时长
        Duration serviceDuration = Duration.between(createTime, endTime);

        // 提取天数和小时数
        long days = serviceDuration.toDays();
        long hours = serviceDuration.toHours() % 24;
        vo.setNumber(days);
        vo.setHours(hours);
        //销售后产品
        vo.setAfterSaleProduct(getOrderGoodsDetail(id));
        // 根据工单ID获取工单详情的工单备件列表
        vo.setOrderDetailWorkSpareList(conWorkSpareService.getOrderDetailWorkSpareList(id));
        //费用记录
        vo.setExpenseRecord(workFeeDetailMapper.getByWorkOrderId(id));
        //事件记录
        vo.setExpenseRecord(workFeeDetailService.getByWorkOrderId(id));
        return vo;
    }

    @Transactional
    public void saveVerifiedVisitTime(AccounLoginInfo loginInfo, OrderVerifyVisitTimeVo verifyVisitTimeVo) {
        // 1. 查询变更前的时间
        ZjWorkDetail oldDetail = workDetailService.getById(verifyVisitTimeVo.getWorkId());
        Date oldVerifiedVisitTime = oldDetail.getVerifiedVisitTime();

        // 2. 更新工单详情
        ZjWorkDetail detail = new ZjWorkDetail();
        detail.setId(verifyVisitTimeVo.getWorkId());
        detail.setVerifiedVisitTime(verifyVisitTimeVo.getVerifiedVisitTime());
        workDetailService.updateById(detail);

        // 3. 写入服务过程日志
        String oldTimeStr = oldVerifiedVisitTime != null ? DateUtil.format(oldVerifiedVisitTime, "yyyy-MM-dd HH:mm") : "无";
        String newTimeStr = verifyVisitTimeVo.getVerifiedVisitTime() != null ? DateUtil.format(verifyVisitTimeVo.getVerifiedVisitTime(), "yyyy-MM-dd HH:mm") : "无";
        String logContent = "变更前核实上门时间：" + oldTimeStr + "，变更后核实上门时间：" + newTimeStr;
        if (verifyVisitTimeVo.getRemark() != null && !verifyVisitTimeVo.getRemark().isEmpty()) {
            logContent += "；备注：" + verifyVisitTimeVo.getRemark();
        }
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, verifyVisitTimeVo.getWorkId(), "客服变更上门时间", logContent));
    }

//    @Scheduled(fixedRate = 600000) // 每10分钟执行一次
//    @Transactional
//    public void checkDispatchNetworkOrderTimeout() {
//        // 获取所有服务商未接单的工单
//        QueryWrapper<ZjWorkDispatchNetwork> queryOrderTimeoutWrapper = new QueryWrapper<>();
//        queryOrderTimeoutWrapper.select("id", "work_id","dispatch_time","status")
//                .eq("status",WorkConstant.DISPATCH_NETWORK_STATUS_1);
//        List<ZjWorkDispatchNetwork> dispatchNetworks = workDispatchNetworkService.list(queryOrderTimeoutWrapper);
//        if (CollectionUtil.isEmpty(dispatchNetworks)) {
//            return;
//        }
//        // 存储 dispatchNetworks 中的 work_id
//        Set<Long> dispatchNetworkWorkIds = dispatchNetworks.stream()
//                .map(ZjWorkDispatchNetwork::getWorkId)
//                .collect(Collectors.toSet());
//        QueryWrapper<ZjWorkOrder> queryWrapper = new QueryWrapper<>();
//        queryWrapper.select("id", "module_id").in("id", dispatchNetworkWorkIds);
//        List<ZjWorkOrder> orderList = workOrderService.list(queryWrapper);
//        // 如果服务商超过x小时未接单，自动退回待派单状态
//        Date currentTime = new Date();
//        for(ZjWorkOrder order : orderList){
//            if (dispatchNetworkWorkIds.contains(order.getId())) {
//
//                //获取派单给网点时间
//                ZjWorkDispatchNetwork dispatchNetwork = dispatchNetworks.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst().orElse(null);
//
//                QueryWrapper<ZjWorkSlaModule> slaModuleWrapper = new QueryWrapper<>();
//                slaModuleWrapper.select("work_sla_id").eq("module_id",order.getModuleId());
//                ZjWorkSlaModule zjWorkSlaModule = zjWorkSlaModuleMapper.selectOne(slaModuleWrapper);
//                if(zjWorkSlaModule == null){
//                    continue;
//                }
//                QueryWrapper<ZjWorkSlaCondition> queryOrderConditionWrapper = new QueryWrapper<>();
//                queryOrderConditionWrapper.select("id", "ageing_time")
//                        .eq("type",3).eq("work_sla_id",zjWorkSlaModule.getWorkSlaId());
//                ZjWorkSlaCondition zjWorkSlaCondition = zjWorkSlaConditionMapper.selectOne(queryOrderConditionWrapper);
//                if(zjWorkSlaCondition == null){
//                    continue;
//                }
//                if (currentTime.after(DateUtils.addHours(dispatchNetwork.getDispatchTime(), zjWorkSlaCondition.getAgeingTime()))) {
//                    if (dispatchNetwork.getStatus() != null && dispatchNetwork.getStatus() == WorkConstant.DISPATCH_NETWORK_STATUS_1) {
//
//                        // 更新工单状态为待派单
//                        UpdateWrapper<ZjWorkOrder> updateOrderWrapper = new UpdateWrapper<>();
//                        updateOrderWrapper.eq("id", dispatchNetwork.getWorkId()).eq("status", WorkConstant.WORK_STATUS_2);
//                        updateOrderWrapper.set("status", WorkConstant.WORK_STATUS_1);
//                        workOrderService.update(updateOrderWrapper);
//                        // 获取工单信息
//                        ZjWorkOrder orderMes = workOrderService.getById(dispatchNetwork.getWorkId());
//                        // 添加工单日志
//                        List<WorkLogVo> networkLogs = new ArrayList<>();
//                        networkLogs.add(new WorkLogVo(
//                                orderMes.getCustAccId(),
//                                "服务商",
//                                orderMes.getId(),
//                                "服务商超过" + zjWorkSlaCondition.getAgeingTime() +"小时未接单",
//                                "工单已自动退回待派单状态"
//                        ));
//                        WorkServiceLog.saveNetwork(networkLogs);
//                        workDispatchNetworkService.removeById(dispatchNetwork.getId());
//                    }
//                }
//            }
//        }
//    }
}
